我最近一直在研究Spring安全性,我知道如何使用数据库动态定义intercept-url(在Spring Security中)。
但我需要重新启动我的Web应用程序以从数据库加载定义的intercept-url。但是当我向数据库添加一个新的拦截网址时我需要加载。
@Component
public class FilterInvocationServiceSecurityMetadataSourceBeanPostProcessor implements BeanPostProcessor {
@Autowired
private FilterInvocationServiceSecurityMetadataSource metadataSource;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof FilterInvocationSecurityMetadataSource) {
return metadataSource;
}
if(bean instanceof FilterChainProxy.FilterChainValidator) {
return new FilterChainProxy.FilterChainValidator() {
@Override
public void validate(FilterChainProxy filterChainProxy) {
}
};
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
@Component("filterInvocationServiceSecurityMetadataSource")
public class FilterInvocationServiceSecurityMetadataSource implements FilterInvocationSecurityMetadataSource, InitializingBean{
private FilterInvocationSecurityMetadataSource delegate;
private RequestConfigMappingService requestConfigMappingService;
private SecurityExpressionHandler<FilterInvocation> expressionHandler;
@Autowired
public FilterInvocationServiceSecurityMetadataSource(CustomWebSecurityExpressionHandler expressionHandler,
RequestConfigMappingService filterInvocationService) {
this.expressionHandler = expressionHandler;
this.requestConfigMappingService = filterInvocationService;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return this.delegate.getAllConfigAttributes();
}
public Collection<ConfigAttribute> getAttributes(Object object) {
return this.delegate.getAttributes(object);
}
public boolean supports(Class<?> clazz) {
return this.delegate.supports(clazz);
}
@Override
public void afterPropertiesSet() throws Exception {
List<RequestConfigMapping> requestConfigMappings = requestConfigMappingService.getRequestConfigMappings();
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>(requestConfigMappings.size());
for(RequestConfigMapping requestConfigMapping : requestConfigMappings) {
RequestMatcher matcher = requestConfigMapping.getMatcher();
requestMap.put(matcher,requestConfigMapping.getAttributes());
}
this.delegate = new ExpressionBasedFilterInvocationSecurityMetadataSource(requestMap, expressionHandler);
}
}
@Repository("requestConfigMappingService")
public class JdbcRequestConfigMappingService implements RequestConfigMappingService {
private SecurityFilterMetaDataService securityFilterMetaDataService;
@Autowired
public JdbcRequestConfigMappingService(SecurityFilterMetaDataService securityFilterMetaDataService) {
if (securityFilterMetaDataService == null) {
throw new IllegalArgumentException("securityFilterMetaDataService cannot be null");
}
this.securityFilterMetaDataService = securityFilterMetaDataService;
}
@Override
public List<RequestConfigMapping> getRequestConfigMappings() {
String pattern = "";
String expressionString = "";
List<SecurityFilterMetaData> securityFilterMetaDataList = securityFilterMetaDataService.getByAscOrder("sortOrder");
List<RequestConfigMapping> requestConfigMappings = new ArrayList<>();
for (SecurityFilterMetaData securityFilterMetaData : securityFilterMetaDataList) {
pattern = securityFilterMetaData.getAntPattern();
expressionString = securityFilterMetaData.getExpression();
AntPathRequestMatcher matcher = new AntPathRequestMatcher(pattern);
requestConfigMappings.add(new RequestConfigMapping(matcher, new SecurityConfig(expressionString)));
}
return requestConfigMappings;
}
private static final class RequestConfigMappingMapper implements RowMapper<RequestConfigMapping> {
@Override
public RequestConfigMapping mapRow(ResultSet rs, int rowNum) throws SQLException {
String pattern = rs.getString("ant_pattern");
String expressionString = rs.getString("expression");
AntPathRequestMatcher matcher = new AntPathRequestMatcher(pattern);
return new RequestConfigMapping(matcher, new SecurityConfig(expressionString));
}
}
}
public interface RequestConfigMappingService {
List<RequestConfigMapping> getRequestConfigMappings();
}
public final class RequestConfigMapping {
private final RequestMatcher matcher;
private final Collection<ConfigAttribute> attributes;
public RequestConfigMapping(RequestMatcher matcher, ConfigAttribute attribute) {
this(matcher, Collections.singleton(attribute));
}
public RequestConfigMapping(RequestMatcher matcher, Collection<ConfigAttribute> attributes) {
if (matcher == null) {
throw new IllegalArgumentException("matcher cannot be null");
}
Assert.notEmpty(attributes, "attributes cannot be null or emtpy");
this.matcher = matcher;
this.attributes = attributes;
}
public RequestMatcher getMatcher() {
return matcher;
}
public Collection<ConfigAttribute> getAttributes() {
return attributes;
}
}
答案 0 :(得分:0)
最后我找到了答案。 FilterInvocationServiceSecurityMetadataSource必须更改。
注意:请记住,对于Spring Security拦截的每个请求,都会调用getAttributes,因此您很可能需要某种缓存。
@Component("filterInvocationServiceSecurityMetadataSource")
public class FilterInvocationServiceSecurityMetadataSource implements FilterInvocationSecurityMetadataSource, InitializingBean{
private FilterInvocationSecurityMetadataSource delegate;
private RequestConfigMappingService requestConfigMappingService;
private SecurityExpressionHandler<FilterInvocation> expressionHandler;
@Autowired
public FilterInvocationServiceSecurityMetadataSource(CustomWebSecurityExpressionHandler expressionHandler,
RequestConfigMappingService filterInvocationService) {
this.expressionHandler = expressionHandler;
this.requestConfigMappingService = filterInvocationService;
}
public Collection<ConfigAttribute> getAllConfigAttributes() {
return this.delegate.getAllConfigAttributes();
}
public Collection<ConfigAttribute> getAttributes(Object object) {
List<RequestConfigMapping> requestConfigMappings = requestConfigMappingService.getRequestConfigMappings();
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>(requestConfigMappings.size());
for(RequestConfigMapping requestConfigMapping : requestConfigMappings) {
RequestMatcher matcher = requestConfigMapping.getMatcher();
requestMap.put(matcher,requestConfigMapping.getAttributes());
}
this.delegate = new ExpressionBasedFilterInvocationSecurityMetadataSource(requestMap, expressionHandler);
return this.delegate.getAttributes(object);
}
public boolean supports(Class<?> clazz) {
return this.delegate.supports(clazz);
}
@Override
public void afterPropertiesSet() throws Exception {
List<RequestConfigMapping> requestConfigMappings = requestConfigMappingService.getRequestConfigMappings();
LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>> requestMap = new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>(requestConfigMappings.size());
for(RequestConfigMapping requestConfigMapping : requestConfigMappings) {
RequestMatcher matcher = requestConfigMapping.getMatcher();
requestMap.put(matcher,requestConfigMapping.getAttributes());
}
this.delegate = new ExpressionBasedFilterInvocationSecurityMetadataSource(requestMap, expressionHandler);
}
}