<bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor"> <property name="authenticationManager" ref="authenticationManager" /> <property name="accessDecisionManager" ref="affirmativeBased" /> <property name="securityMetadataSource" ref="securityMetadataSource" /> </bean> <bean id="securityMetadataSource" class="com.jaeson.springstudy.security.URLFilterInvocationSecurityMetadataSource"> <property name="resourceRepository" ref="resourceRepository" /> </bean> <bean id="resourceRepository" class="com.jaeson.springstudy.security.ResourceRepository"> <property name="dataSource" ref="dataSource" /> </bean> <bean id="affirmativeBased" class="org.springframework.security.access.vote.AffirmativeBased"> <constructor-arg type="java.util.List"> <list> <ref bean="expressionVoter" /> <ref bean="roleVoter" /> <ref bean="authenticatedVoter" /> </list> </constructor-arg> </bean> <bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter" /> <bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter" /> <bean id="expressionVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter"> <property name="expressionHandler" ref="expressionHandler" /> </bean> <bean id="expressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler" />
package com.jaeson.springstudy.security;
import java.util.*;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
public class ResourceRepository {
private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public Map<String,String> getURLResourceMapping() {
String sql = "SELECT r2.resource_path as path, r1.rolename as auth FROM role_resource rr " +
"JOIN role r1 ON rr.role_id = r1.id " +
"JOIN resources r2 ON rr.resource_id = r2.id " +
"ORDER BY r2.priority DESC";
Map<String, String> result = new LinkedHashMap<String, String>();
List<Map<String, Object>> list = this.jdbcTemplate.queryForList(sql);
for (Map<String, Object> row : list) {
String path = (String) row.get("path");
String auth = (String) row.get("auth");
if (result.containsKey(path)) {
String tmp = result.get(path);
result.put(path, tmp + "," + auth);
} else {
result.put(path, auth);
}
}
return result;
}
}
package com.jaeson.springstudy.security;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Collections;
import java.util.Set;
import java.util.LinkedHashMap;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
public class URLFilterInvocationSecurityMetadataSource implements
FilterInvocationSecurityMetadataSource, InitializingBean {
protected final Logger logger = LoggerFactory.getLogger(getClass());
//权限集合
private Map<RequestMatcher, Collection<ConfigAttribute>> requestMap;
@Autowired
private ResourceRepository resourceRepository;
public void setResourceRepository(ResourceRepository resourceRepository) {
this.resourceRepository = resourceRepository;
}
@Override
public Collection<ConfigAttribute> getAttributes(Object object)
throws IllegalArgumentException {
final HttpServletRequest request = ((FilterInvocation) object).getRequest();
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
.entrySet()) {
if (entry.getKey().matches(request)) {
return entry.getValue();
}
}
return Collections.emptyList();
}
@Override
public Collection<ConfigAttribute> getAllConfigAttributes() {
Set<ConfigAttribute> allAttributes = new HashSet<ConfigAttribute>();
for (Map.Entry<RequestMatcher, Collection<ConfigAttribute>> entry : requestMap
.entrySet()) {
allAttributes.addAll(entry.getValue());
}
return allAttributes;
}
@Override
public boolean supports(Class<?> clazz) {
return FilterInvocation.class.isAssignableFrom(clazz);
}
@Override
public void afterPropertiesSet() throws Exception {
this.requestMap = bindRequestMap();
}
public void refreshResuorceMap() {
this.requestMap = bindRequestMap();
}
protected Map<RequestMatcher, Collection<ConfigAttribute>> bindRequestMap() {
Map<RequestMatcher, Collection<ConfigAttribute>> map =
new LinkedHashMap<RequestMatcher, Collection<ConfigAttribute>>();
Map<String, String> resourceMapping = this.resourceRepository.getURLResourceMapping();
for (Map.Entry<String,String> entry : resourceMapping.entrySet()) {
String key = entry.getKey();
Collection<ConfigAttribute> atts = SecurityConfig.createListFromCommaDelimitedString(entry.getValue());
map.put(new AntPathRequestMatcher(key), atts);
}
return map;
}
}