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
欢迎关注个人公众号一起交流学习: