package cn.mb.cloud.auth.config; import cn.mb.cloud.auth.security.component.MbCloudAuthUser; import cn.mb.cloud.auth.security.component.MbCloudWebResponseExceptionTranslator; import cn.mb.cloud.auth.security.service.MbCloudClientDetailsService; import cn.mb.cloud.auth.security.service.MbCloudUserAuthDetailsService; import cn.mb.cloud.auth.security.service.impl.MbCloudRedisTokenStore; import cn.mb.cloud.common.core.constant.SecurityConstants; import lombok.AllArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer; import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter; import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer; import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer; import org.springframework.security.oauth2.provider.token.TokenEnhancer; import org.springframework.security.oauth2.provider.token.TokenEnhancerChain; import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; import javax.sql.DataSource; import java.util.Arrays; import java.util.HashMap; import java.util.Map; /** * @author jason * 认证服务器配置 */ @Configuration @AllArgsConstructor @EnableAuthorizationServer public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter { private final DataSource dataSource; private final MbCloudUserAuthDetailsService cloudUserDetailsService; private final AuthenticationManager authenticationManager; private final RedisConnectionFactory redisConnectionFactory; @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { MbCloudClientDetailsService clientDetailsService = new MbCloudClientDetailsService(dataSource); clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT); clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT); clients.withClientDetails(clientDetailsService); } @Override public void configure(AuthorizationServerSecurityConfigurer oauthServer) { oauthServer .allowFormAuthenticationForClients() .checkTokenAccess("isAuthenticated()"); } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) { //token增强配置 TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain(); tokenEnhancerChain.setTokenEnhancers(Arrays.asList(tokenEnhancer(), jwtAccessTokenConverter())); endpoints .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST) .tokenStore(redisTokenStore()) .tokenEnhancer(tokenEnhancerChain) .userDetailsService(cloudUserDetailsService) .authenticationManager(authenticationManager) .reuseRefreshTokens(false) .exceptionTranslator(new MbCloudWebResponseExceptionTranslator()); } @Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter(); tokenConverter.setSigningKey(SecurityConstants.TOKEN_SIGN_KEY); return tokenConverter; } /** * tokenstore 定制化处理 * * @return TokenStore */ @Bean public MbCloudRedisTokenStore redisTokenStore() { MbCloudRedisTokenStore tokenStore = new MbCloudRedisTokenStore(redisConnectionFactory); tokenStore.setPrefix(SecurityConstants.REDIS_TOKEN_STORE_PREFIX); return tokenStore; } @Bean public TokenEnhancer tokenEnhancer() { return (accessToken, authentication) -> { if (SecurityConstants.CLIENT_CREDENTIALS .equals(authentication.getOAuth2Request().getGrantType())) { return accessToken; } final Map additionalInfo = new HashMap<>(8); MbCloudAuthUser cloudUser = (MbCloudAuthUser) authentication.getUserAuthentication().getPrincipal(); additionalInfo.put("user_id", cloudUser.getId()); additionalInfo.put("username", cloudUser.getUsername()); ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo); return accessToken; }; } }