spring security 资源判断时不执行自定义AccessDecisionManager

本文解决SpringSecurity框架中资源请求无法有效拦截的问题,介绍如何通过调整Filter顺序和配置确保权限检查正常工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        弄这个框架的时候,因为这个问题困扰了很久,一直显示无法进入AccessDecisionManager内,导致资源请求无法进行有效拦截,资料找了很久也并未找到合理解决方案,表示当时就脑子不够用,及看不懂源码,又不懂原理,搭建都是靠人家的教程,一开始也看到了一篇类似的博文,但没太在意,事实证明也正是因为那个原因导致,

博文内容如下:

     

原文地址:http://blog.163.com/jiawei28888@126/blog/static/799737692015217103427362/

随后,根据此提示修改了相应代码,

@Override
	public Collection<ConfigAttribute> getAttributes(Object obj)
			throws IllegalArgumentException {
		// TODO Auto-generated method stub
		//获取请求的url地址
		String url = ((FilterInvocation)obj).getRequestUrl();
		System.out.println("FilterInvocationSecurityMetadataSourceImpl:getAttributes()---------------请求地址为:"+url);
		
		Collection<ConfigAttribute> collection = new LinkedList<>();
		
		//查询数据库中是否存在此链接
		List<ModuleApRole> moduleApRoleList = moduleMapper.selectByUri(url);
		for (ModuleApRole moduleApRole : moduleApRoleList) {
			if (moduleApRole.getRole_id() != null) {
				ConfigAttribute configAttribute = new SecurityConfig(moduleApRole.getRole_id()+"");
				collection.add(configAttribute);
			}
		}
		
		//防止数据库中没有数据,不能进行权限拦截
		if(collection.size()<1){
			ConfigAttribute configAttribute = new SecurityConfig("ROLE_NO_USER");
			collection.add(configAttribute);
		}
		return collection;
	}

  这样框架在解析的时候就会判断此请求有效,然后再进入AccessDecisionManager的decide()进行资源权限的验证,实测是可以的,还有一种方法听说是重写AbstractSecurityInterceptor的方法实现。至于为什么collection在返回的时候不能为空,那不管,那是框架定的规则。


还有一种,是资源拦截不准确,可能出现的情况有如下两种情况:

  • 1.使用了Struts2+spring框架,在web.xml文件,<filter>标签时 Struts2配置到了spring security上面,由于web.xml配置文件中执行顺序是从上至下,所以可能会导致资源请求时被Struts2先拦截,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>adsystem</display-name>
  <welcome-file-list>
  
  <welcome-file>wrt/manage/main.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- Spring 配置 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml,classpath:applicationContext-Security.xml,classpath:applicationContext-mybatis.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
	<!-- Spring 刷新Introspector防止内存泄露 -->
	<listener>
		<listener-class>
			org.springframework.web.util.IntrospectorCleanupListener
		</listener-class>
	</listener>
	
	<!--  防止多人登陆 ,控制一个用户只能登录一次,不能在其他地方重新登录-->
	<listener>
		<listener-class>
			org.springframework.security.web.session.HttpSessionEventPublisher 
		</listener-class>
	</listener>
	
	<!-- session超时定义,单位为分钟 -->
	<session-config>
		<session-timeout>20</session-timeout>
	</session-config>
	
 
  <!-- Struts2配置  使用默认-->
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>
  
  
  <!-- Spring Security 安全管理机制 -->
  <filter>
       <filter-name>springSecurityFilterChain</filter-name>
       <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
   <filter-mapping>
       <filter-name>springSecurityFilterChain</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>


  

    <!-- 配置log4j配置文件的路径,可以是xml或 properties(此参数必须配)--> 
	<!-- 下面使用了classpath 参数指定log4j.properties文件的位置,这样log4j的配置文件就不用非要放到src的下面 -->
	<context-param>
	   <param-name>log4jConfigLocation</param-name>
	 <param-value>classpath:config/log4j.properties</param-value>
	 
	</context-param> 
	<!-- 使用spring的监听器,当应用启动时来读取log4j的配置文件 -->
	<listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>
    
</web-app>


更正为:


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>adsystem</display-name>
  <welcome-file-list>
  
  <welcome-file>wrt/manage/main.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- Spring 配置 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml,classpath:applicationContext-Security.xml,classpath:applicationContext-mybatis.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
	<!-- Spring 刷新Introspector防止内存泄露 -->
	<listener>
		<listener-class>
			org.springframework.web.util.IntrospectorCleanupListener
		</listener-class>
	</listener>
	
	<!--  防止多人登陆 ,控制一个用户只能登录一次,不能在其他地方重新登录-->
	<listener>
		<listener-class>
			org.springframework.security.web.session.HttpSessionEventPublisher 
		</listener-class>
	</listener>
	
	<!-- session超时定义,单位为分钟 -->
	<session-config>
		<session-timeout>20</session-timeout>
	</session-config>
  
  
  <!-- Spring Security 安全管理机制 -->
  <filter>
       <filter-name>springSecurityFilterChain</filter-name>
       <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
   <filter-mapping>
       <filter-name>springSecurityFilterChain</filter-name>
       <url-pattern>/*</url-pattern>
   </filter-mapping>


  <!-- Struts2配置  使用默认-->
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>
  

    <!-- 配置log4j配置文件的路径,可以是xml或 properties(此参数必须配)--> 
	<!-- 下面使用了classpath 参数指定log4j.properties文件的位置,这样log4j的配置文件就不用非要放到src的下面 -->
	<context-param>
	   <param-name>log4jConfigLocation</param-name>
	 <param-value>classpath:config/log4j.properties</param-value>
	 
	</context-param> 
	<!-- 使用spring的监听器,当应用启动时来读取log4j的配置文件 -->
	<listener>
	<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>
    
</web-app>

  • 资源不能被拦截,配置属于失效情况,可能是在applicationContext-Security.xml配置文件中,忘了将安全访问策略配置上去,<security:custom-filter ref="myFilterSecurityInterceptor" before="FILTER_SECURITY_INTERCEPTOR"/>    
 

更改后,


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值