Spring Security – 忽略请求参数规则的Url

我有一个使用spring安全性的Web应用程序。 它使用元素来描述不同URL的访问filter。 默认情况下,这不会考虑URL的请求参数。 我需要根据请求参数设置url的自定义安全规则。 所以我做了以下事情:

1)我创建了一个bean后处理器类,它将为spring安全机制启用请求参数选项:

  . . .    . . .  

和代码:

 public class MySecurityBeanPostProcessor implements BeanPostProcessor { private Boolean stripQueryStringFromUrls = null; @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof DefaultFilterInvocationSecurityMetadataSource && stripQueryStringFromUrls != null) { ((DefaultFilterInvocationSecurityMetadataSource) bean) .setStripQueryStringFromUrls(stripQueryStringFromUrls.booleanValue()); } return bean; } // code stripped for clarity } 

这应该设置spring安全元数据源以考虑请求参数。 我已经调试了上面的代码,并且正在设置stripQueryStringFromUrls属性。

2)在我的安全上下文xml中,我有以下定义:

   ...  

正如您所看到的,我只有在用户未经过身份validation或使用来宾帐户时才需要使用指定的参数访问URL。 另外,我为同一个url添加了规则,但没有任何没有filter的参数。

据我所知,应该配置Spring安全性,在不太具体的情况下提供更具体的URL,否则链将首先检测更一般的规则,而不会继续更具体的规则。 这就是为什么我希望带有params的url更具体,因此被拒绝访问经过身份validation的非来宾用户。 相反,下面定义的更一般的规则适用。 这是输出:

INFO [STDOUT] 186879 [http-0.0.0.0-8080-1] DEBUG org.springframework.security.web.FilterChainProxy – 候选人是:’/ myUrl’; pattern是/ myUrl; 匹配=真

INFO [STDOUT] 186879 [http-0.0.0.0-8080-1] DEBUG org.springframework.security.web.FilterChainProxy – / myUrl?param = value有一个空的过滤列表

我还尝试删除没有参数的url规则。 然后,filter选择/**模式并要求用户登录,而不是使用params工作的url规则。 输出是:

INFO [STDOUT] 73066 [http-0.0.0.0-8080-1] DEBUG org.springframework.security.web.FilterChainProxy – 候选人是:’/ myUrl’; 模式是/ **; 匹配=真

INFO [STDOUT] 73068 [http-0.0.0.0-8080-1] DEBUG org.springframework.security.web.FilterChainProxy – / myUrl?param =附加滤波器链中位置1的8的值; 触发filter:’SecurityContextPersistenceFilter’

该应用程序是用Java 1.6编写的,使用Spring v3.0并部署在JBoss v5.1.0-GA上,在linux机器上。 我没有线索为什么filter按照我描述的方式运行。 非常感谢您的帮助和建议。


编辑:

作为结论,我观察到从未应用/myUrl?param=valuefilter – 好像忽略了security-context.xml中的条目。 这符合我迄今为止观察到的行为。 我也尝试用access="permitAll"替换filters="none" ,切换到正则表达式(并相应地更改模式 – 例如/myUrl?param=value变为\A/myUrl\?param=value\Z )并且在所有变化我得到的行为是一样的。


编辑2:

这里描述的问题实际上是无效的。 原因如下:出现问题的项目由于内部库冲突和不兼容而排除了一些弹簧包,而整个设置在某种程度上起作用。 我从来没有意识到这一点,实际上这种不合适的配置使整个问题过时了。 具体原因是isAuthenticated()和isAnonymous()方法的实现没有按预期工作,因此这里提供的任何建议都不起作用。

在Spring Security 3.0中,这是(可以理解)混淆的一个常见原因,因为filters="none"的使用会向FilterChainProxy添加一个带有空filter列表的模式,而使用access属性会添加一个安全访问规则FilterSecurityInterceptor ,用于保护URL。

匹配过程是:

  1. FilterChainProxy将请求与filter链匹配
  2. 如果filter链非空,则FilterSecurityInterceptor将检查请求

这两个类都维护一个单独的有序匹配列表,它们按照您定义它们的顺序应用它们,但是您需要了解下面实际上有两个单独的bean被配置而没有直接连接。

在一个简单的命名空间应用程序中, 块正在使用pattern /**FilterChainProxy添加单个filter链。 您添加的任何filters="none"模式都会在实际链之前放置空filter链。

Spring Security 3.1中的情况有了很大改进,因为您通过使用单独的块来配置单独的filter链,该块更直观地映射到bean级别的实际情况。 请求匹配过程也得到了很大改进,现在使用RequestMatcher接口来处理所有事情。 在配置块时,您也可以使用它而不是模式。

所以,你最好的选择可能是升级。 然后,您可以实现一个RequestMatcher ,它检查您要查找的参数是否存在,比如MyParamRequestMatcher ,然后使用:

      

请注意,使用URL模式匹配参数通常不是很安全,因为它很容易通过重新排序URL,添加伪造模式等来绕过。 您的情况可能没问题,因为带参数的版本允许不安全的访问,并且您的模式需要对其他情况进行身份validation。

如果你想继续使用3.0,你最好的选择是避免使用filters="none ”(改为使用isAnonymous() )并且可能使用正则表达式匹配而不是ant路径,这样你就可以更容易地匹配查询字符串。 我再次重申,这种方式定义的规则几乎肯定会被绕过,所以不要依赖它们来提高安全性,并确保默认情况下你是安全的。


更新:

作为我对使用正则表达式匹配和permitAll建议的测试,如果我在Spring Security的3.0.x分支中修改“教程”示例应用程序,如下所示:

      ...  

然后我确实得到了预期的行为:

 [DEBUG,FilterChainProxy] Candidate is: '/secure/index.jsp?param=value'; pattern is /.*; matched=true [DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 1 of 12 in additional filter chain; firing Filter: 'ConcurrentSessionFilter' ... [DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 11 of 12 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' [DEBUG,FilterChainProxy] /secure/index.jsp?param=value at position 12 of 12 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' [DEBUG,ExpressionBasedFilterInvocationSecurityMetadataSource] Candidate is: '/secure/index.jsp?param=value'; pattern is \A/secure/extreme/.*\Z; matched=false [DEBUG,ExpressionBasedFilterInvocationSecurityMetadataSource] Candidate is: '/secure/index.jsp?param=value'; pattern is \A/secure/index.jsp\?param=value\Z; matched=true [DEBUG,FilterSecurityInterceptor] Secure object: FilterInvocation: URL: /secure/index.jsp?param=value; Attributes: [permitAll] 

它显示了.*后面的FilterChainProxy匹配,后跟FilterSecurityInterceptor与参数匹配的确切URL。