Spring Security如何使用URL地址进行权限控制

 更新时间:2019年12月12日 08:30:44   作者:二刀  
这篇文章主要介绍了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权限控制

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringMVC 单文件,多文件上传实现详解

    SpringMVC 单文件,多文件上传实现详解

    这篇文章主要介绍了SpringMVC 单文件,多文件上传实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • 浅谈Java虚拟机对内部锁的四种优化方式

    浅谈Java虚拟机对内部锁的四种优化方式

    这篇文章主要介绍了浅谈Java虚拟机对内部锁的四种优化方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • Java常用集合与原理解析

    Java常用集合与原理解析

    这篇文章主要介绍了Java常用集合与原理解析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • 基于Spring中的事务@Transactional细节与易错点、幻读

    基于Spring中的事务@Transactional细节与易错点、幻读

    这篇文章主要介绍了基于Spring中的事务@Transactional细节与易错点、幻读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java中生成唯一ID的方法示例

    Java中生成唯一ID的方法示例

    这篇文章主要介绍了Java中生成唯一ID的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • JVM钩子函数的使用场景详解

    JVM钩子函数的使用场景详解

    当jvm进程退出的时候,或者受到了系统的中断信号,hook线程就会启动,一个线程可以注入多个钩,下面这篇文章主要给大家介绍了关于JVM钩子函数使用的相关资料,需要的朋友可以参考下
    2021-08-08
  • java中String,数组,ArrayList三者之间的转换

    java中String,数组,ArrayList三者之间的转换

    这篇文章主要介绍了java中String,数组,ArrayList三者之间的转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 详解Java设计模式编程中的访问者模式

    详解Java设计模式编程中的访问者模式

    这篇文章主要介绍了Java设计模式编程中的访问者模式,访问者模式的合理利用可以避免项目中出现大量重复的代码,需要的朋友可以参考下
    2016-02-02
  • 使用Java实现生命游戏串行代码示例

    使用Java实现生命游戏串行代码示例

    生命游戏是一种二维细胞自动机,由英国数学家在1970年发明,在游戏的过程中,细胞会形成各种有规律的结构,展现出生命的复杂性和多样性,本文通过java和JavaFX实现了一个简单的生命游戏,可以直观的观察到细胞的迭代过程,需要的朋友可以参考下
    2024-10-10
  • MyBatisPlus使用@TableField注解处理默认填充时间的问题

    MyBatisPlus使用@TableField注解处理默认填充时间的问题

    这篇文章主要介绍了MyBatisPlus使用@TableField注解处理默认填充时间的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01

最新评论