com.healthy.security.server.AppSecurityBeanConfig Maven / Gradle / Ivy
package com.healthy.security.server;
import cn.hutool.core.collection.ListUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.healthy.common.security.properties.SecurityProperties;
import com.healthy.security.server.handler.HealthyAccessDeniedHandler;
import com.healthy.security.server.handler.HealthyAuthenticationEntryPoint;
import com.healthy.security.server.kickout.KickOutPostProcessor;
import com.healthy.security.server.kickout.impl.RedisKickOutPostProcessor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
import org.springframework.security.oauth2.provider.token.*;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Collections;
/**
* Default policy configuration in browser environment. You can override the default
* configuration by declaring beans of the same type or the same name.
*
* @author xiaomingzhang
*/
@Configuration
public class AppSecurityBeanConfig {
@Resource
private SecurityProperties securityProperties;
@Resource
private DataSource dataSource;
@Resource
private UserDetailsService userDetailsService;
@Resource
private AuthenticationEventPublisher authenticationEventPublisher;
@Resource
private ObjectMapper objectMapper;
@Resource
private RedisTemplate redisTemplate;
@Resource
private RedisConnectionFactory redisConnectionFactory;
@Bean
public ClientDetailsService clientDetails() {
return new JdbcClientDetailsService(dataSource);
}
@Bean
@ConditionalOnMissingBean(AccessDeniedHandler.class)
public AccessDeniedHandler accessDeniedHandler() {
HealthyAccessDeniedHandler accessDeniedHandler = new HealthyAccessDeniedHandler();
accessDeniedHandler.setObjectMapper(objectMapper);
return accessDeniedHandler;
}
@Bean
@ConditionalOnMissingBean(AuthenticationEntryPoint.class)
public AuthenticationEntryPoint authenticationEntryPoint(KickOutPostProcessor kickOutPostProcessor) {
HealthyAuthenticationEntryPoint authenticationEntryPoint = new HealthyAuthenticationEntryPoint();
authenticationEntryPoint.setKickOutPostProcessor(kickOutPostProcessor);
return authenticationEntryPoint;
}
@Bean
@ConditionalOnMissingBean(KickOutPostProcessor.class)
public KickOutPostProcessor kickOutPostProcessor() {
RedisKickOutPostProcessor kickOutPostProcessor = new RedisKickOutPostProcessor();
kickOutPostProcessor.setKickOutCachePrefix(securityProperties.getOauth2().getKickOutCachePrefix());
kickOutPostProcessor.setRedisTemplate(redisTemplate);
return kickOutPostProcessor;
}
@Bean
@Primary
public HealthyTokenServices healthyTokenServices(ClientDetailsService clientDetailsService, TokenStore tokenStore,
TokenEnhancerChain tokenEnhancerChain, KickOutPostProcessor kickOutPostProcessor) {
HealthyTokenServices tokenServices = new HealthyTokenServices();
tokenServices.setKickOut(securityProperties.getOauth2().isKickOut());
tokenServices.setReuseRefreshToken(securityProperties.getOauth2().isReuseRefreshToken());
tokenServices.setTokenStore(tokenStore);
tokenServices.setSupportRefreshToken(true);
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setKickOutPostProcessor(kickOutPostProcessor);
tokenServices.setTokenEnhancer(tokenEnhancerChain);
PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
provider.setPreAuthenticatedUserDetailsService(new UserDetailsByNameServiceWrapper<>(userDetailsService));
ProviderManager providerManager = new ProviderManager(Collections.singletonList(provider));
providerManager.setAuthenticationEventPublisher(authenticationEventPublisher);
tokenServices.setAuthenticationManager(providerManager);
return tokenServices;
}
@Bean
@ConditionalOnMissingBean(AuthenticationKeyGenerator.class)
public AuthenticationKeyGenerator authenticationKeyGenerator() {
return new DefaultAuthenticationKeyGenerator();
}
@Bean
@ConditionalOnMissingBean(TokenStore.class)
public TokenStore tokenStore(AuthenticationKeyGenerator authenticationKeyGenerator) {
RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
redisTokenStore.setPrefix(securityProperties.getOauth2().getRedisTokenStorePrefix());
redisTokenStore.setAuthenticationKeyGenerator(authenticationKeyGenerator);
return redisTokenStore;
}
@Bean
@ConditionalOnMissingBean(name = "healthyTokenEnhancer")
public TokenEnhancer healthyTokenEnhancer() {
return new HealthyTokenEnhancer();
}
@Bean
public TokenEnhancerChain tokenEnhancerChain(
@Qualifier(value = "healthyTokenEnhancer") TokenEnhancer tokenEnhancer) {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
enhancerChain.setTokenEnhancers(ListUtil.toList(tokenEnhancer));
return enhancerChain;
}
@Bean
@ConditionalOnProperty(prefix = "healthy.security.oauth2", name = "jwt-token", havingValue = "true")
public JwtAccessTokenConverter jwtAccessTokenConverter(
@Qualifier("healthyTokenEnhancer") TokenEnhancer tokenEnhancer, TokenEnhancerChain tokenEnhancerChain) {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(securityProperties.getOauth2().getJwtSigningKey());
tokenEnhancerChain.setTokenEnhancers(ListUtil.toList(tokenEnhancer, converter));
return converter;
}
@Bean
public TokenStoreUtil tokenStoreUtil() {
return new TokenStoreUtil();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy