1. 程式人生 > 程式設計 >Spring Security如何使用URL地址進行許可權控制

Spring Security如何使用URL地址進行許可權控制

這篇文章主要介紹了Spring Security如何使用URL地址進行許可權控制,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

目的是:系統記憶體在很多不同的使用者,每個使用者具有不同的資源訪問許可權,具體表現就是某個使用者對於某個URL是無許可權訪問的。需要Spring Security忙我們過濾。

FilterSecurityInterceptor是Spring Security進行URL許可權判斷的,FilterSecurityInterceptor又繼承於AbstractSecurityInterceptor,由此可推測,我們可以新增一個Interceptor繼承AbstractSecurityInterceptor,實現我們自己的許可權校驗邏輯。

檢視父類及其程式碼邏輯,有幾點必須要注意:

1、主要鑑權方法是呼叫父類中accessDecisionManager的decide值,所以我們需要自己實現一個accessDecisionManager

2、父類中存在抽象方法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許可權控制

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。