基于JWT实现SSO单点登录流程图解

  一、基于JWT实现SSO单点登录原理

  1、什么是单点登录

  所谓单点登录就是有多个应用部署在不同的服务器上,只需登录一次就可以互相访问不同服务器上的资源。

  2、单点登录流程

  当一个访问请求发给应用A,如果这个请求需要登录以后才能访问,那么应用A就会向认证服务器请求授权,这时候就把用户引导到认证服务器上。用户在认证服务器上完成认证并授权。认证授权完成后,认证服务器返回给应用A一个授权码,应用A携带授权码到认证服务器请求令牌,认证服务器返回应用A一个JWT,应用A解析JWT里面的信息,完成登录。这是一个标准的OAuth2的授权码流程。

  走完认证流程后,给出去的JWT实际上里面包含的就是当前用户在认证服务器上登录以后用户的认证信息,应用A解析JWT后,自己生成一个经过认证的Authentication放到它的SpringSecurity和SecurityContext里面。

  当访问应用服务器B的时候,同样引导用户去认证服务器请求授权(不需要登录),用户授权可以用登录的信息去访问应用B,后面同样是授权码流程,返回JWT给应用B。两个应用返回不同的JWT,但是解析出的信息是一样的。

  二、实现单点登录

  1、父工程(sso-demo)

  1)pom.xml

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>2.0.4.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.security.oauth.boot</groupId>
      <artifactId>spring-security-oauth2-autoconfigure</artifactId>
      <version>2.1.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-jwt</artifactId>
      <version>1.0.10.RELEASE</version>
    </dependency>
  </dependencies>
</dependencyManagement>

  2、认证服务(sso-server)

  1)pom.xml

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.security.oauth.boot</groupId>
  <artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-jwt</artifactId>
</dependency>

  2)application.properties

server.port = 9999
server.servlet.context-path = /server

  3)WebSecurityConfig.java

@EnableWebSecurity
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

  @Override
  protected void configure(HttpSecurity http) throws Exception {
    http.httpBasic().and().csrf().disable();
  }
  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }
}

  4)MyUserDetailsService.java

@Component
public class MyUserDetailsService implements UserDetailsService{

  @Autowired
  private PasswordEncoder passwordEncoder;

  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
    System.out.println("登录用户名:"+username);
    String password = passwordEncoder.encode("123456");
    return new User(username,password,true,true,true,true,
        AuthorityUtils.commaSeparatedStringToAuthorityList("all"));
  }
}

  5)SsoAuthorizationServerConfig.java

@Configuration
@EnableAuthorizationServer
public class SsoAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

  @Autowired
  private PasswordEncoder passwordEncoder;

  @Override
  public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    clients.inMemory()
        .withClient("appclient_1").secret(passwordEncoder.encode("client1_123456"))
        .authorizedGrantTypes("authorization_code","refresh_token")
        .scopes("all")
        .redirectUris("http://127.0.0.1:8080/client1/login")
       .and()
        .withClient("appclient_2").secret(passwordEncoder.encode("client2_123456"))
        .authorizedGrantTypes("authorization_code","refresh_token")
        .scopes("all")
        .redirectUris("http://127.0.0.1:8060/client2/login");
  }
  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints.tokenStore(jwtTokenStore()).accessTokenConverter(jwtAccessTokenConverter());
  }
  @Override
  public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    security.tokenKeyAccess("isAuthenticated()");//访问tokenKey(秘钥shxiang)的时候需要身份认证
  }
  @Bean
  public TokenStore jwtTokenStore() {
    return new JwtTokenStore(jwtAccessTokenConverter());
  }
  @Bean
  public JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
    accessTokenConverter.setSigningKey("shxiang");//设置秘钥
    return accessTokenConverter;
  }
}

  6)SsoServerApplication.java

@SpringBootApplication
public class SsoServerApplication {
  public static void main(String[] args) {
    SpringApplication.run(SsoServerApplication.class, args);
  }
}

  3、应用1(sso-client1)

  1)pom.xml,同上

  2)application.properties

security.oauth2.client.client-id = appclient_1
security.oauth2.client.client-secret = client1_123456
security.oauth2.client.user-authorization-uri = http://127.0.0.1:9999/server/oauth/authorize

security.oauth2.client.access-token-uri = http://127.0.0.1:9999/server/oauth/token
security.oauth2.resource.jwt.key-uri = http://127.0.0.1:9999/server/oauth/token_key

server.port=8080
server.servlet.context-path =/client1

  3)index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SSO Client1</title>
</head>
<body>
  <h1>SSO Demo Client1</h1>
  <a href="http://127.0.0.1:8060/client2/index.html" rel="external nofollow" >访问Client2</a>
</body>
</html>

  4)SsoClient1Application.java

@SpringBootApplication
@RestController
@EnableOAuth2Sso
public class SsoClient1Application {
  public static void main(String[] args) {
    SpringApplication.run(SsoClient1Application.class, args);
  }
  @GetMapping("/user")
  public Authentication user(Authentication user) {
    return user;
  }
}

  4、应用2(sso-client2)

  1)pom.xml,同上

  2)application.properties,类比应用1修改

  3)index.html,类比应用1修改

  4)SsoClient2Application.java,同上

  5、测试

  1)浏览器输入:127.0.0.1:8080/client1/index.html

  2)用户名随便输入,密码输入123456

  3)点击Authorize 

  4)点击超级链接访问Client2

  5)点击Authorize

  认证成功,后面点击两个超级链接可以任意访问,无需登录 、无需点击Authorize。

  注意:

  1)虽是同一用户,但是访问http://127.0.0.1:8080/client1/user和http://127.0.0.1:8060/client2/user获取的Token值不一样。

  2)实现跳过授权,登录后直接访问,修改如下代码:

  3)表单登录与httpBasic登录,修改WebSecurityConfig.java中configure方法

httpBasic登录:http.httpBasic().and().csrf().disable();
表单登录:http.formLogin().and().authorizeRequests().anyRequest().authenticated();

  4)重点:浏览器访问要用127.0.0.1不要用localhost。要设置应用路径server.servlet.context-path =/xxxx,不能直接到端口号。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot整合SSO(single sign on)单点登录

    1.单点登录三种常见的方式 (1)Session广播机制(Session复制) (2)使用Cookie+Redis实现 (3)使用token实现 2.单点登录介绍 举例: (1)引入jwt依赖 <!-- JWT--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> </dependency> (2)创建JWTUtil

  • 基于springboot和redis实现单点登录

    本文实例为大家分享了基于springboot和redis实现单点登录的具体代码,供大家参考,具体内容如下 1.具体的加密和解密方法 package com.example.demo.util; import com.google.common.base.Strings; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.Cipher; import javax.crypto.KeyG

  • JavaScript实现单点登录的示例

    项目中遇到单点登录这个问题,当点击链接的时候跳转到另一个系统中并实现自动登录进去,直接进去系统的页面 因为不同的系统涉及到跨域的问题,所以使用nginx来解决跨域的问题 先跳转到另一个系统的一个页面,在这个页面里实现登录操作再跳转到系统中我们需要的页面 还有一个问题就是登录的时候需要用户名和密码,用户名和密码不是固定的,需要动态获取,所以跳转到过渡页面的时候需要携带参数 携带参数是通过url传递的,这里用户名和密码使用了简单的base64加密 过渡页面接受参数 var params = wind

  • 基于SpringBoot+Redis的Session共享与单点登录详解

    前言 使用Redis来实现Session共享,其实网上已经有很多例子了,这是确保在集群部署中最典型的redis使用场景.在SpringBoot项目中,其实可以一行运行代码都不用写,只需要简单添加添加依赖和一行注解就可以实现(当然配置信息还是需要的). 然后简单地把该项目部署到不同的tomcat下,比如不同的端口(A.B),但项目访问路径是相同的.此时在A中使用set方法,然后在B中使用get方法,就可以发现B中可以获取A中设置的内容. 但如果就把这样的一个项目在多个tomcat中的部署说实现了单

  • 使用springboot结合vue实现sso单点登录

    本文实例为大家分享了springboot vue实现sso单点登录的具体代码,供大家参考,具体内容如下 项目结构: 开发工具:idea, maven3 静态文件下载地址 1.pom文件: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.or

  • 详解使用JWT实现单点登录(完全跨域方案)

    首先介绍一下什么是JSON Web Token(JWT)? 官方文档是这样解释的:JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,可以在各方之间作为JSON对象安全地传输信息.此信息可以通过数字签名进行验证和信任.JWT可以使用秘密(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名. 虽然JWT可以加密以在各方之间提供保密,但只将专注于签名令牌.签名令牌可以验证其中包含的声明的完整性,而加密令牌则隐藏其他方的声明.当使用公钥

  • 单点登录的三种实现方式

    前言 在 B/S 系统中,登录功能通常都是基于 Cookie 来实现的.当用户登录成功后,一般会将登录状态记录到 Session 中,或者是给用户签发一个 Token,无论哪一种方式,都需要在客户端保存一些信息(Session ID 或 Token ),并要求客户端在之后的每次请求中携带它们.在这样的场景下,使用 Cookie 无疑是最方便的,因此我们一般都会将 Session 的 ID 或 Token 保存到 Cookie 中,当服务端收到请求后,通过验证 Cookie 中的信息来判断用户是否

  • springboot集成CAS实现单点登录的示例代码

    最近新参与的项目用到了cas单点登录,我还不会,这怎么能容忍!空了学习并搭建了一个spring-boot 集成CAS 的demo.实现了单点登录与登出. 单点登录英文全称是:Single Sign On,简称SSO. 含义:在多个相互信任的系统中,只要登录一个系统其他系统均可访问. CAS 是一种使用广泛的单点登录实现,分为客户端CAS Client和服务端 CAS Service,客户端就是我们的系统,服务端是认证中心,由CAS提供,我们需要稍作修改,启动起来就可以用.~~~~ 效果演示 ht

  • 基于JWT实现SSO单点登录流程图解

    一.基于JWT实现SSO单点登录原理 1.什么是单点登录 所谓单点登录就是有多个应用部署在不同的服务器上,只需登录一次就可以互相访问不同服务器上的资源. 2.单点登录流程 当一个访问请求发给应用A,如果这个请求需要登录以后才能访问,那么应用A就会向认证服务器请求授权,这时候就把用户引导到认证服务器上.用户在认证服务器上完成认证并授权.认证授权完成后,认证服务器返回给应用A一个授权码,应用A携带授权码到认证服务器请求令牌,认证服务器返回应用A一个JWT,应用A解析JWT里面的信息,完成登录.这是一

  • Spring Security基于JWT实现SSO单点登录详解

    SSO :同一个帐号在同一个公司不同系统上登陆 使用SpringSecurity实现类似于SSO登陆系统是十分简单的 下面我就搭建一个DEMO 首先来看看目录的结构 其中sso-demo是父工程项目 sso-client .sso-client2分别对应2个资源服务器,sso-server是认证服务器 引入的pom文件 sso-demo <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q

  • 一个注解搞定Spring Security基于Oauth2的SSO单点登录功能

    目录 一.说明 二.原理说明 2.1. 同域单点登录 2.2. 跨域单点登录 2.3. 基于Oauth2的跨域单点登录流程 三.Spring Security实现 四.demo下载地址 一.说明 单点登录顾名思义就是在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统,免除多次登录的烦恼.本文主要介绍 同域 和 跨域 两种不同场景单点登录的实现原理,并使用 Spring Security 来实现一个最简单的跨域 SSO客户端 . 二.原理说明 单点登录主流都是基于共享 cookie

  • 基于Security实现OIDC单点登录的详细流程

    目录 一.说明 二.OIDC核心概念 三.什么是IDToken 3.1.与JWT的AccessToken区别 3.2.与UserInfo端点的区别 四.OIDC单点登录流程 五.SpringSecurity实现 六.完整的demo下载地址 一.说明 本文主要是给大家介绍 OIDC 的核心概念以及如何通过对 Spring Security 的授权码模式进行扩展来实现 OIDC 的单点登录. OIDC 是 OpenID Connect 的简称,OIDC=(Identity, Authenticati

  • springboot 集成cas5.3 实现sso单点登录详细流程

    什么是单点登录? 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 我们目前的系统存在诸多子系统,而这些子系统是分别部署在不同的服务器中,那么使用传统方式的session是无法解决的,我们需要使用相关的单点登录技术来解决. SSO单点登录访问流程主要有以下步骤: 访问服务:SSO客户端发送请求访问应用系统提供的服务资源. 定向认证:SSO客户端会重定向用户请求

  • GoLang jwt无感刷新与SSO单点登录限制解除方法详解

    目录 前言 为什么使用JWT Cookie和Session token (header.payload.signature) token 安全性 基于token安全性的处理 客户端与服务端基于无感刷新流程图 golang实现atoken和rtoken 颁发token 校验token 无感刷新token 完整实现代码 SSO(Single Sign On)单用户登录以及无感刷新token 实现思路 实战代码 小结 前言 为什么使用JWT Jwt提供了生成token以及token验证的方法,而tok

  • 入门到精通Java SSO单点登录原理详解

    目录 1. 基础概念 2. 单点登录 3. CAS 流程 4. OAuth 流程 5. CAS和OAuth的区别 1. 基础概念 SSO单点登录(Single sign-on) 所谓单点登录就是在多个应用系统中,用户只需登录一次就可以访问所有相互信任的系统. CAS 中央认证服务(Central Authentication Service) CAS是由美国耶鲁大学发起的一个企业级开源项目,旨在为WEB应用系统提供一种可靠的单点登录解决方案(WEB SSO). OAuth2.0 开放授权(Ope

  • SpringCloud实现SSO 单点登录的示例代码

    前言 作为分布式项目,单点登录是必不可少的,文本基于之前的的博客(猛戳:SpringCloud系列--Zuul 动态路由,SpringBoot系列--Redis)记录Zuul配合Redis实现一个简单的sso单点登录实例 sso单点登录思路: 1.访问分布式系统的任意请求,被Zuul的Filter拦截过滤 2.在run方法里实现过滤规则:cookie有令牌accessToken且作为key存在于Redis,或者访问的是登录页面.登录请求则放行 3.否则,将重定向到sso-server的登录页面且

  • SpringBoot如何实现同域SSO(单点登录)

    单点登录,其实看起来不是很复杂,只是细节上的处理,单点区分有三种 同域SSO 同父域SSO 跨域的SSO 如何实现同域SSO? 个人理解:当用户登录访问demo1.lzmvlog.top时,同时具有访问demo2.lzmvlog.top的能力,即认证完成一次,可以访问所有系统. 实现方式:可以采用Cookie实现,即用户在访问一个系统时,携带认证颁发的信息,系统响应是否具有访问资格,否则跳转认证,也可以采用Session,即Session共享,校验访问用户是否具有有效的信息,提供访问资格 代码实

  • SSO单点登录的PHP实现方法(Laravel框架)

    Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来:它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁.富于表达力. 简单说一下我的逻辑,我也不知道我理解sso对不对. 假如三个站点 a.baidu.com b.baidu.com c.baidu.com a.baidu.com 作为验证用户登录账户. b和c作为客户端(子系统). b和c需要登录的时候跳转到a,并且携带参数source指明登陆后跳转的链接

随机推荐