<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; } }
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; } }