目的是:系統內存在不少不一樣的用戶,每一個用戶具備不一樣的資源訪問權限,具體表現就是某個用戶對於某個URL是無權限訪問的。須要Spring Security忙咱們過濾。
本文的不少命名都是參考連接博文的,最大的不一樣應該是本文是基於Spring boot,再次也向前人致敬!
由上一篇可知,FilterSecurityInterceptor是Spring Security進行URL權限判斷的,
FilterSecurityInterceptor又繼承於AbstractSecurityInterceptor,由此可推測,咱們能夠新增一個Interceptor繼承
AbstractSecurityInterceptor,實現咱們本身的權限校驗邏輯。
查看父類及其代碼邏輯,有幾點必需要注意:
一、主要鑑權方法是調用父類中accessDecisionManager的decide值,因此咱們須要本身實現一個
accessDecisionManager
二、父類中存在抽象方法public abstract SecurityMetadataSource obtainSecurityMetadataSource();做用是獲取URL及用戶角色對應的關係。咱們須要加入本身的實現。
如下是部分代碼實現
主要攔截器JwtUrlSecurityInterceptor,須要在WebSecurityConfig(Spring Security配置)文件中註冊
//這個攔截器用來實現按照用戶權限,對所請求的url進行攔截 @Bean public JwtUrlSecurityInterceptor jwtUrlSecurityInterceptorBean() throws Exception{ return new JwtUrlSecurityInterceptor(); }@Override protected void configure(HttpSecurity httpSecurity) throws Exception {... httpSecurity.addFilterBefore(jwtUrlSecurityInterceptorBean(), FilterSecurityInterceptor.class);... }
實現自定義的
accessDecisionManager
package org.zerhusen.security.dsuri;import org.springframework.security.access.AccessDecisionManager;import org.springframework.security.access.AccessDeniedException;import org.springframework.security.access.ConfigAttribute;import org.springframework.security.authentication.InsufficientAuthenticationException;import org.springframework.security.core.Authentication;import java.util.Collection;/** * Created by dingshuo on 2017/6/28. */public class MyAccessDecisionManager implements AccessDecisionManager { @Override public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { System.out.println("自定義的接口"); throw new AccessDeniedException("no right"); } @Override public boolean supports(ConfigAttribute attribute) { return true; } @Override public boolean supports(Class<?> clazz) { return true; }}
實現自定義的資源
SecurityMetadataSource
package org.zerhusen.security.dsuri;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 java.util.*;/** * Created by dingshuo on 2017/6/28. */public class MyInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource { private static Map<String, Collection<ConfigAttribute>> resourceMap = null; @Autowired UrlMatcher urlMatcher; public MyInvocationSecurityMetadataSource() {//這裏能夠查數據庫實現//注入dao便可 resourceMap = new HashMap<String, Collection<ConfigAttribute>>(); Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>(); ConfigAttribute ca = new SecurityConfig("ROLE_USER1"); atts.add(ca); resourceMap.put("/index.jsp", atts); Collection<ConfigAttribute> attsno =new ArrayList<ConfigAttribute>(); ConfigAttribute cano = new SecurityConfig("ROLE_NO"); attsno.add(cano); resourceMap.put("/other.jsp", attsno); } @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { String url = ((FilterInvocation)object).getRequestUrl(); Iterator<String> ite = resourceMap.keySet().iterator(); while (ite.hasNext()) { String resURL = ite.next(); if (url.equals("/protected")) { return resourceMap.get(resURL); } } return null; } @Override public Collection<ConfigAttribute> getAllConfigAttributes() { return null; } @Override public boolean supports(Class<?> clazz) { return true; }}
實現
JwtUrlSecurityInterceptor
package org.zerhusen.security.dsuri;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.security.access.AccessDecisionManager;import org.springframework.security.access.SecurityMetadataSource;import org.springframework.security.access.intercept.AbstractSecurityInterceptor;import org.springframework.security.access.intercept.InterceptorStatusToken;import org.springframework.security.authentication.AuthenticationManager;import org.springframework.security.web.FilterInvocation;import javax.servlet.*;import java.io.IOException;/** * Created by dingshuo on 2017/6/28. */public class JwtUrlSecurityInterceptor extends AbstractSecurityInterceptor implements Filter { @Autowired public void setMyAccessDecisionManager(){ super.setAccessDecisionManager(myAccessDecisionManagerBean()); } @Bean public MyAccessDecisionManager myAccessDecisionManagerBean(){ return new MyAccessDecisionManager(); } @Bean public MyInvocationSecurityMetadataSource myInvocationSecurityMetadataSourceBean(){ return new MyInvocationSecurityMetadataSource(); } @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); } @Override public void destroy() { } @Override public Class<?> getSecureObjectClass() { return FilterInvocation.class; } @Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.myInvocationSecurityMetadataSourceBean(); } public void invoke(FilterInvocation fi) throws IOException, ServletException { InterceptorStatusToken token = super.beforeInvocation(fi); try { fi.getChain().doFilter(fi.getRequest(), fi.getResponse()); }finally { super.afterInvocation(token, null); } }}
如上是簡單的URL權限控制