處理token時間、存儲策略,客戶端配置等git
之前的都是spring security oauth默認的token生成策略,token默認在org.springframework.security.oauth2.provider.token.DefaultTokenServices 類裏生成的,感興趣能夠看看github
/** * 認證服務器 * ClassName: ImoocAuthenticationServerConfig * @Description: TODO * @author lihaoyang * @date 2018年3月12日 */ @Configuration @EnableAuthorizationServer //這個註解就是實現了一個認證服務器 public class ImoocAuthenticationServerConfig { }
是uuid,如今作自定義token,token是在認證服務器裏生成的,須要在認證服務器也就是ImoocAuthenticationServerConfig 裏寫代碼。redis
認證服務器配置:spring
/** * 認證服務器 * 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相關配置類:windows
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 app
imooc.security.oauth2.clients[1].clientId = test
imooc.security.oauth2.clients[1].clientSecret = testide
啓動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