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

 

 欢迎关注个人公众号一起交流学习: