• Spring Security构建Rest服务-1204-Spring Security OAuth开发APP认证框架之Token处理


    token处理之一基本参数配置

    处理token时间、存储策略,客户端配置等

     

    以前的都是spring security oauth默认的token生成策略,token默认在org.springframework.security.oauth2.provider.token.DefaultTokenServices 类里生成的,感兴趣可以看看

    /**
     * 认证服务器
     * ClassName: ImoocAuthenticationServerConfig 
     * @Description: TODO
     * @author lihaoyang
     * @date 2018年3月12日
     */
    @Configuration
    @EnableAuthorizationServer //这个注解就是实现了一个认证服务器
    public class ImoocAuthenticationServerConfig {
    
    }

    是uuid,现在做自定义token,token是在认证服务器里生成的,需要在认证服务器也就是ImoocAuthenticationServerConfig 里写代码。

    认证服务器配置:

    /**
     * 认证服务器
     * ClassName: ImoocAuthenticationServerConfig 
     * @Description: 
     * extends AuthorizationServerConfigurerAdapter 自定义token生成
     * @author lihaoyang
     * @date 2018年3月12日
     */
    @Configuration
    @EnableAuthorizationServer //这个注解就是实现了一个认证服务器
    public class ImoocAuthenticationServerConfig extends AuthorizationServerConfigurerAdapter{
    
        /*
         * 不继承AuthorizationServerConfigurerAdapter,这些bean会自己找,配了,就要自己实现 
         */
        
        @Autowired
        private AuthenticationManager authenticationManager;
        
        @Autowired
        private  UserDetailsService userDetailsService;
        
        //配置文件
        @Autowired
        private SecurityProperties securityProperties;
        
        //token存在redis,默认是在内存
        @Autowired
        private TokenStore tokenStore;
        
        /**
         * 配置TokenEndpoint 是  /oauth/token处理的入口点
         */
        @Override
        public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
            endpoints.tokenStore(tokenStore)
                     .authenticationManager(authenticationManager)
                     .userDetailsService(userDetailsService);
        }
        
        /**
         * 功能:认证服务器会给哪些第三方应用发令牌
         *        覆盖了该方法,application.properties里配置的
         *                 security.oauth2.client.clientId = imooc
         *                security.oauth2.client.clientSecret = imoocsecret
         *     就失效了
         */
        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            //1,写死
    //        clients.jdbc(dataSource)就是qq场景用的,有第三方公司注册过来,目前场景是给自己的应用提供接口,所以用内存就行
    //        clients.inMemory()
    //                //~========================== 在这里配置和写配置文件一样================
    //                .withClient("imooc") //第三方应用用户名
    //                .secret("imoocsecret") //密码                       
    //                .accessTokenValiditySeconds(7200)//token有效期
    //                .authorizedGrantTypes("password","refresh_token") //支持的授权模式
    //                .scopes("all","read","write") //相当于oauth的权限,这里配置了,请求里的必须和这里匹配
    //                //~=======如果有多个client,这里继续配置
    //                .and()
    //                .withClient("xxxxx"); 
            
            //2,读取配置文件
            InMemoryClientDetailsServiceBuilder builder = clients.inMemory();
            //判断是否配置了客户端
            if(ArrayUtils.isNotEmpty(securityProperties.getOauth2().getClients())){
                for (OAuth2ClientProperties config : securityProperties.getOauth2().getClients()) {
                    builder.withClient(config.getClientId())
                            .secret(config.getClientSecret())
                            .accessTokenValiditySeconds(config.getAccessTokenValiditySeconds())
                            .authorizedGrantTypes("password","refresh_token") //这些也可以配置也可以写死,看心情
                            .scopes("all","read","write"); 
                }
            }
            
        }
    }

    Token默认是存在内存的,这样服务器重启后,就需要重新登录,所以存在redis,(先有个redis,我是装了个windows版的)比存在数据库好,需要配置:

    /**
     * token存储到redis,默认是在内存不行
     * ClassName: TokenStoreConfig 
     * @Description:  token存储策略
     * @author lihaoyang
     * @date 2018年3月15日
     */
    @Configuration
    public class TokenStoreConfig {
    
        @Autowired
        private RedisConnectionFactory redisConnectionFactory;
        
        @Bean
        public TokenStore redisTokenStore(){
            return new RedisTokenStore(redisConnectionFactory);
        }
        
    }

    OAuth相关配置类:

    package com.imooc.security.core.properties;
    
    /**
     * 接口授权客户端配置 ClassName: OAuth2ClientProperties
     * 
     * @Description: 接口授权客户端配置
     * @author lihaoyang
     * @date 2018年3月15日
     */
    public class OAuth2ClientProperties {
    
        private String clientId;
    
        private String clientSecret;
    
        private int accessTokenValiditySeconds = 3600; //没配置就用默认值
        
        // xxxxx在这里扩展配置
    
        public String getClientId() {
            return clientId;
        }
    
        public void setClientId(String clientId) {
            this.clientId = clientId;
        }
    
        public String getClientSecret() {
            return clientSecret;
        }
    
        public void setClientSecret(String clientSecret) {
            this.clientSecret = clientSecret;
        }
    
        public int getAccessTokenValiditySeconds() {
            return accessTokenValiditySeconds;
        }
    
        public void setAccessTokenValiditySeconds(int accessTokenValiditySeconds) {
            this.accessTokenValiditySeconds = accessTokenValiditySeconds;
        }
    
    }
    package com.imooc.security.core.properties;
    
    /**
     * 多个接口客户端,是数组,只有一个的话就不用这个了
     * ClassName: OAuth2Properties 
     * @Description: TODO
     * @author lihaoyang
     * @date 2018年3月15日
     */
    public class OAuth2Properties {
        
        private OAuth2ClientProperties[] clients = {};
    
        public OAuth2ClientProperties[] getClients() {
            return clients;
        }
    
        public void setClients(OAuth2ClientProperties[] clients) {
            this.clients = clients;
        }
        
        
    
    }

    这样只需要在application.properties里配置客户端,可以配置fuo

    #第三方应用client_id

    imooc.security.oauth2.clients[0].clientId = imooc
    imooc.security.oauth2.clients[0].clientSecret = imoocsecret
    #token失效时间
    imooc.security.oauth2.clients[0].accessTokenValiditySeconds = 3600

    imooc.security.oauth2.clients[1].clientId = test
    imooc.security.oauth2.clients[1].clientSecret = test

     启动demo项目,测试:

    redis是空的:

    1,模拟获取手机验证码

    2,手机验证码登录

    响应:

    {
    "access_token": "ca7417ef-2792-4c81-b441-519f29046cae",
    "token_type": "bearer",
    "refresh_token": "f32a845b-5b2b-4761-ab0e-ec076c6c0280",
    "expires_in": 3599,
    "scope": "all read write"
    }

    redis中存了很多key:

    拿token访问用户信息:

    响应

    总结:

    1,认证服务器 ImoocAuthenticationServerConfig 需要继承 AuthorizationServerConfigurerAdapter ,来自定义token的存储、客户端的配置。

    2,自定义TokenStoreConfig配置类,存储token在redis中。

    2,token默认存在内存中,这样不行,一般存在redis中,所以需要一个redis

    存在问题,token失效的时候,redis中的key还存在,怎么给删除了呢?

     具体代码在github:https://github.com/lhy1234/spring-security

    下一步自定义token的生成策略,用JWT

  • 相关阅读:
    [LeetCode] 399. Evaluate Division Java
    图的遍历
    [LeetCode] 332. Reconstruct Itinerary Java
    [LeetCode] 310. Minimum Height Trees Java
    sql like 查询
    递归树
    用SQL语句,删除掉重复项只保留一条
    Exception in thread “main” com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String
    如何利用java得到当前的时间和前一天的时间
    Java 字符串用逗号并接
  • 原文地址:https://www.cnblogs.com/lihaoyang/p/8573966.html
Copyright © 2020-2023  润新知