基于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)l
<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)l
<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
t-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 = de("123456");
return new User(username,password,true,true,true,true,
AuthorityUtilsmaSeparatedStringToAuthorityList("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").de("client1_123456"))
.authorizedGrantTypes("authorization_code","refresh_token")
.
scopes("all")
.redirectUris("127.0.0.1:8080/client1/login")
.and()
.withClient("appclient_2").de("client2_123456"))
.authorizedGrantTypes("authorization_code","refresh_token")
.scopes("all")
.redirectUris("127.0.0.1:8060/client2/login");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
@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)l,同上
  2)application.properties
security.oauth2.client.client-id = appclient_1
security.oauth2.client.client-secret = client1_123456
security.oauth2.client.user-authorization-uri = 127.0.0.1:9999/server/oauth/authorize security.oauth2.client.access-token-uri = 127.0.0.1:9999/server/oauth/token
source.jwt.key-uri = 127.0.0.1:9999/server/oauth/token_key
server.port=8080
t-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="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;
}
spring framework是什么框架的
}
  4、应⽤2(sso-client2)
  1)l,同上
  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。
  注意:
  2)实现跳过授权,登录后直接访问,修改如下代码:
  3)表单登录与httpBasic登录,修改WebSecurityConfig.java中configure⽅法
httpBasic登录:http.httpBasic().and().csrf().disable();
表单登录:http.formLogin().and().authorizeRequests().anyRequest().authenticated();
  4)重点:浏览器访问要⽤127.0.0.1不要⽤localhost。要设置应⽤路径t-path =/xxxx,不能直接到端⼝号。以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。