spring security 的权限控制有两种方式,一种是比较当前请求url和当前用户所拥有的权限中是否包含该url;java
另外一种是利用@PreAuthorize("hasAuthority('XXX')")注解的方式,其中xxx能够为角色role,也能够为任意的权限标识符,是个string类型web
1)注解的方式spring
须要在websecurityconfig文件上加上@EnableGlobalMethodSecurity(prePostEnabled = true)//开启security注解apache
而后在loaduserdetail方法中加上该用户所拥有的权限api
最后在方法上加注解@PreAuthorize("hasAuthority('XXX')")ide
2)是利用Spring security拦截的方式post
MyAccessDecisionManager.java文件this
import org.springframework.security.access.AccessDecisionManager; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.ConfigAttribute; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Service; import java.util.Collection; import java.util.Iterator; @Service public class MyAccessDecisionManager implements AccessDecisionManager{ //决定是否拥有权限的决策方法 @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(null== configAttributes || configAttributes.size() <=0) { return; } ConfigAttribute c; String needRole; for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) { c = iter.next(); needRole = c.getAttribute(); for(GrantedAuthority ga : authentication.getAuthorities()) {//authentication 为在注释1 中循环添加到 GrantedAuthority 对象中的权限信息集合 if(needRole.trim().equals(ga.getAuthority())) { return; } } } throw new AccessDeniedException("no right"); } @Override public boolean supports(ConfigAttribute attribute) { return false; } @Override public boolean supports(Class<?> clazz) { return true; } }
MyFilterSecurityInterceptor.java文件url
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.SecurityMetadataSource; import org.springframework.security.access.intercept.AbstractSecurityInterceptor; import org.springframework.security.access.intercept.InterceptorStatusToken; import org.springframework.security.web.FilterInvocation; import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource; import org.springframework.stereotype.Service; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import java.io.IOException; //@Service public class MyFilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { @Autowired private FilterInvocationSecurityMetadataSource securityMetadataSource; @Autowired public void setMyAccessDecisionManager(MyAccessDecisionManager myAccessDecisionManager) { super.setAccessDecisionManager(myAccessDecisionManager); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { FilterInvocation fi = new FilterInvocation(request, response, chain); invoke(fi); } private void invoke(FilterInvocation fi) throws IOException, ServletException { //fi里面有一个被拦截的url //里面调用MyInvocationSecurityMetadataSource的getAttributes(Object object)这个方法获取fi对应的全部权限 //再调用MyAccessDecisionManager的decide方法来校验用户的权限是否足够 InterceptorStatusToken token = super.beforeInvocation(fi); try { //执行下一个拦截器 fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); } finally { super.afterInvocation(token, null); } } @Override public void destroy() { } @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.securityMetadataSource; } }
MyInvocationSecurityMetadataSourceService.java文件code
import com.lenovo.scct.trackingapi.model.auth.AutResource; import com.lenovo.scct.trackingapi.repository.auth.MenuRepository; import com.lenovo.scct.trackingapi.service.auth.MenuService; import org.apache.commons.lang.StringUtils; 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.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @Service public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource { @Autowired MenuRepository menuRepository; private HashMap<String, Collection<ConfigAttribute>> map = null; /** * 加载权限表中全部的权限 */ public void loadResource() { map = new HashMap<>(); Collection<ConfigAttribute> array; ConfigAttribute configAttribute; List<AutResource> resourceList = menuRepository.getMenuResource("lujia3"); for (AutResource autResource : resourceList) { if (StringUtils.isBlank(autResource.getResourceUrl())) { autResource.setResourceUrl("/authorization/**/buttons"); autResource.setResourceName("xxx"); } array = new ArrayList<>(); configAttribute = new SecurityConfig(autResource.getResourceName()); array.add(configAttribute); map.put(autResource.getResourceUrl(), array); } } @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { if (map == null) loadResource(); //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; } }