@Configuration
@Order(Integer.MIN_VALUE)
@EnableAuthorizationServer
public class AuthorizationConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
JdbcClientDetailsService clientDetailsService = new JdbcClientDetailsService(dataSource);
clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT);
clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT);
clients.withClientDetails(clientDetailsService);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
//token增強配置
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
tokenEnhancerChain.setTokenEnhancers(
Arrays.asList(tokenEnhancer(), jwtAccessTokenConverter()));
endpoints
.tokenStore(redisTokenStore())
.tokenEnhancer(tokenEnhancerChain)
.authenticationManager(authenticationManager)
.reuseRefreshTokens(false)
.userDetailsService(userDetailsService);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security
.allowFormAuthenticationForClients()
.tokenKeyAccess("isAuthenticated()")
.checkTokenAccess("permitAll()");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter jwtAccessTokenConverter() {
MSJwtAccessTokenConverter MSJwtAccessTokenConverter = new MSJwtAccessTokenConverter();
MSJwtAccessTokenConverter.setSigningKey(CommonConstant.SIGN_KEY);
return MSJwtAccessTokenConverter;
}
/**
* tokenstore 定制化處理
*
* @return TokenStore
* 1. 如果使用的 redis-cluster 模式請使用 MSRedisTokenStore
* MSRedisTokenStore tokenStore = new MSRedisTokenStore();
* tokenStore.setRedisTemplate(redisTemplate);
*/
@Bean
public TokenStore redisTokenStore() {
RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
tokenStore.setPrefix(SecurityConstants.MS_PREFIX);
return tokenStore;
}
/**
* jwt 生成token 定制化處理
*
* @return TokenEnhancer
*/
@Bean
public TokenEnhancer tokenEnhancer() {
return (accessToken, authentication) -> {
final Map<String, Object> additionalInfo = new HashMap<>(2);
additionalInfo.put("license", SecurityConstants.MS_LICENSE);
UserDetailsImpl user = (UserDetailsImpl) authentication.getUserAuthentication().getPrincipal();
if (user != null) {
additionalInfo.put("userId", user.getUserId());
}
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
return accessToken;
};
}}
1.繼承AuthorizationServerConfigurerAdapter,此類包含授權的方法 對進行配置
2.AuthorizationServerEndpointsConfigurer 令牌端點的存儲方式,本地使用InMemoryTokenStore 此處配置了redis的存儲方式 生產環境可以進行使用
3.AuthorizationServerSecurityConfigurer 中的permitAll() 讓本身的oauth的訪問不需要授權 ,isAuthenticated()檢查access_token需要進行授權
4.SecurityClientDetailsServiceImpl 實現客戶端自定義配置