Spring Cloud Security 整合 JWT

Spring Cloud Security 整合 JWT 实现令牌存储

  • 一、基础概述
  • 二、利用Redis存储令牌
  • 三、利用JWT存储令牌
  • 四、扩展JWT的存储内容
  • 五、解析JWT存储的内容

一、基础概述

  • 在Oauth2 + Spring Cloud Security的项目环境中, Spring Cloud Security 默认把访问令牌保存在内存中。而在分布式环境中,我们可以利用JWT或Redis存储令牌信息,以便于多个服务的使用。

  • JWT是JSON WEB TOKEN的缩写,它是基于 RFC 7519 标准定义的一种可以安全传输的的JSON对象,由于使用了数字签名,所以是可信任和安全的。

  • JWT token 的格式为 header.payload.signature

    • header

      {
        "alg": "HS256",
        "typ": "JWT"
      }
      
    • payload

      {
        "exp": 1572682831,
        "user_name": "zhangsan",
        "authorities": [
          "client"
        ],
        "jti": "c1a0645a-28b5-4468-b4c7-9623131853af",
        "client_id": "admin",
        "scope": [
          "all"
        ]
      }
      
    • signature

      signature为以header和payload生成的签名,一旦header和payload被篡改,验证将失败

  • JWT token 的官网:https://jwt.io/

    Spring Cloud Security 整合 JWT_第1张图片

二、利用Redis存储令牌

  • 添加依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-data-redisartifactId>
    dependency>
    
  • 添加配置

    server:
      port: 8080
      servlet:
        context-path: /
    
    spring:
      application:
        name: oauth-redis
      redis:
        database: 0
        host: 127.0.0.1
        port: 6379
        password: 
    
  • 添加Redis存储配置类

    @Configuration
    public class RedisTokenStoreConfig {
    
        @Autowired
        private RedisConnectionFactory redisConnectionFactory;
    
        @Bean
        public TokenStore redisTokenStore (){
            return new RedisTokenStore(redisConnectionFactory);
        }
    }
    
  • 修改认证服务器配置类

    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @Autowired
        private UserDetailServiceImpl userDetailsService;
    
        @Autowired
        @Qualifier("redisTokenStore")
        private TokenStore tokenStore;
        
        /**
         * 使用密码模式所需配置
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            endpoints.authenticationManager(authenticationManager)
                    .userDetailsService(userDetailsService)
                	// 配置令牌存储策略
                	.tokenStore(tokenStore);
        }
    }
    
  • 获取访问令牌

    使用Postman工具

    Spring Cloud Security 整合 JWT_第2张图片

    Spring Cloud Security 整合 JWT_第3张图片

    Spring Cloud Security 整合 JWT_第4张图片

  • 查看Redis信息

    Spring Cloud Security 整合 JWT_第5张图片

三、利用JWT存储令牌

  • 添加JWT存储配置类

    @Configuration
    public class JwtTokenStoreConfig {
    
        @Bean
        public TokenStore jwtTokenStore() {
            return new JwtTokenStore(jwtAccessTokenConverter());
        }
    
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
            // 配置JWT使用的秘钥
            accessTokenConverter.setSigningKey("test_key");
            return accessTokenConverter;
        }
    }
    
  • 修改认证服务器配置类

    @Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @Autowired
        private UserDetailServiceImpl userDetailsService;
    
        @Autowired
        @Qualifier("jwtTokenStore")
        private TokenStore tokenStore;
        @Autowired
        private JwtAccessTokenConverter jwtAccessTokenConverter;
        
        /**
         * 使用密码模式所需配置
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            endpoints.authenticationManager(authenticationManager)
                    .userDetailsService(userDetailsService)
                	// 配置令牌存储策略
                	.tokenStore(tokenStore)
                    .accessTokenConverter(jwtAccessTokenConverter);
        }
    }
    
  • 获取访问令牌

    使用Postman工具

    Spring Cloud Security 整合 JWT_第6张图片

    Spring Cloud Security 整合 JWT_第7张图片

    Spring Cloud Security 整合 JWT_第8张图片

  • 查看JWT信息

    将得到的 access_token 去https://jwt.io/ 网站进行解析

    Spring Cloud Security 整合 JWT_第9张图片

四、扩展JWT的存储内容

  • 添加内容扩展类

    public class JwtTokenEnhancer implements TokenEnhancer {
        
        @Override
        public OAuth2AccessToken enhance(
            	OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
            
            Map<String, Object> info = new HashMap<>();
            info.put("add_key", "add_value");
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
            
            return accessToken;
        }
    }
    
  • 修改JWT存储配置类

    @Configuration
    public class JwtTokenStoreConfig {
    
        @Bean
        public TokenStore jwtTokenStore() {
            return new JwtTokenStore(jwtAccessTokenConverter());
        }
    
        @Bean
        public JwtAccessTokenConverter jwtAccessTokenConverter() {
            JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
            // 配置JWT使用的秘钥
            accessTokenConverter.setSigningKey("test_key");
            return accessTokenConverter;
        }
        
        @Bean
        public JwtTokenEnhancer jwtTokenEnhancer() {
            return new JwtTokenEnhancer();
        }
    }
    
  • 修改认证服务器配置类

    ![20210325194754](C:/Users/jihongye/Documents/Scrshot/20210325194754.png@Configuration
    @EnableAuthorizationServer
    public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    
        @Autowired
        private PasswordEncoder passwordEncoder;
    
        @Autowired
        private AuthenticationManager authenticationManager;
    
        @Autowired
        private UserDetailServiceImpl userDetailsService;
    
        @Autowired
        @Qualifier("jwtTokenStore")
        private TokenStore tokenStore;
        @Autowired
        private JwtAccessTokenConverter jwtAccessTokenConverter;
        @Autowired
        private JwtTokenEnhancer jwtTokenEnhancer;
        
        /**
         * 使用密码模式所需配置
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
            TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
            
            List<TokenEnhancer> delegates = new ArrayList<>();
            delegates.add(jwtTokenEnhancer); 
            delegates.add(jwtAccessTokenConverter);
            
            enhancerChain.setTokenEnhancers(delegates);
            
            endpoints.authenticationManager(authenticationManager)
                    .userDetailsService(userDetailsService)
                	// 配置令牌存储策略
                	.tokenStore(tokenStore)
                    .accessTokenConverter(jwtAccessTokenConverter)
                	.tokenEnhancer(enhancerChain);
        }
    }
    
  • 查看JWT信息

    Spring Cloud Security 整合 JWT_第10张图片

五、解析JWT存储的内容

  • 添加依赖

    <dependency>
        <groupId>io.jsonwebtokengroupId>
        <artifactId>jjwtartifactId>
        <version>0.9.0version>
    dependency>
    
  • 测试使用

    public class ApplicationTest {
        
        public void test() {
             public void test() {
            String token = "jwt的token字符串";
            
            Object obj = Jwts.parser()
                    .setSigningKey("test_key".getBytes(StandardCharsets.UTF_8))
                    .parseClaimsJws(token)
                    .getBody();
            
         	System.out.println(object);   
        }   
        }
    }
    

【源码地址】:GitHub

你可能感兴趣的:(Spring,Cloud,Java,java,微服务)