package com.tianbo.warehouse.security; import com.tianbo.warehouse.dao.PERMISSIONMapper; import com.tianbo.warehouse.model.PERMISSION; 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.AntPathRequestMatcher; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.*; /** * 本类的主要功能就是通过当前的请求地址,获取该地址需要的用户角色 * 如果getAttributes(Object o)方法返回null的话,意味着当前这个请求不需要任何角色就能访问,甚至不需要登录。 */ @Service public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource{ @Autowired PERMISSIONMapper permissionMapper; private HashMap<String, Collection<ConfigAttribute>> map =null; /** * 加载权限表中所有权限 */ public void loadResourceDefine(String requestUrl){ map = new HashMap<>(); Collection<ConfigAttribute> array; ConfigAttribute cfg; List<PERMISSION> permissions = permissionMapper.findAll(); for(PERMISSION permission : permissions) { array = new ArrayList<>(); //此处只添加了用户的名字,其实还可以添加更多权限的信息, // 例如请求方法到ConfigAttribute的集合中去。 // 此处添加的信息将会作为MyAccessDecisionManager类的decide的第三个参数。 //CFG存储访问的URL需要的权限"ROLE_??"LIST List<String> urlOfRoles = permissionMapper.findRoleListByUrl(requestUrl); for (String roleName:urlOfRoles) { cfg = new SecurityConfig(roleName); array.add(cfg); } //用权限的getUrl() 作为map的key,用ConfigAttribute的集合作为 value, map.put(permission.getUrl(), array); } } /** * 此方法是为了判定用户请求的url 是否在权限表中, * 如果在权限表中,则返回给 decide 方法, * 用来判定用户是否有此权限。如果不在权限表中则放行。 * 如果getAttributes(Object o)方法返回null的话,意味着当前这个请求不需要任何角色就能访问 * getAttributes(Object o)方法返回的集合最终会来到AccessDecisionManager类中 */ @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { //清楚地址 String requestUrl = ((FilterInvocation)object).getRequestUrl(); if(map ==null) {loadResourceDefine(requestUrl);} //object 中包含用户请求的request 信息 HttpServletRequest request = ((FilterInvocation) object).getHttpRequest(); AntPathRequestMatcher matcher; String resUrl; for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext(); ) { resUrl = iter.next(); matcher = new AntPathRequestMatcher(resUrl); if(matcher.matches(request)) { return map.get(resUrl); } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> clazz) { return true; } }