【发布时间】:2012-02-13 01:11:13
【问题描述】:
我有一个使用 Spring Security 的 Web 应用程序。它使用<intercept-url ../> 元素来描述不同url 的访问过滤器。默认情况下,这不考虑 url 的请求参数。我需要根据请求参数设置 url 的自定义安全规则。所以我做了以下事情:
1) 我创建了一个 bean 后处理器类,它将为 spring 安全机制启用请求参数选项:
<beans:beans>
. . .
<beans:bean class="MySecurityBeanPostProcessor">
<beans:property name="stripQueryStringFromUrls" value="false" />
</beans:bean>
. . .
</beans:beans>
还有代码:
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 中,我有以下定义:
<intercept-url pattern="/myUrl?param=value" access="!isAuthenticated() or hasRole('ROLE_GUEST')" />
<intercept-url pattern="/myUrl" filters="none" />
...
<intercept-url pattern="/**" access="isAuthenticated()" />
如您所见,仅当用户未通过身份验证或使用访客帐户时,我才需要使用指定的参数访问 url。另外,我为相同的 url 添加了一条规则,但没有任何参数,没有过滤器。
据我所知,spring security 应该配置提供更具体的 url BEFORE 不太具体的,否则链将首先检测到更一般的规则并且不会继续越具体。这就是为什么我希望带有参数的 url 更具体,因此被拒绝访问经过身份验证的非来宾用户。相反,下面定义的更一般的规则适用。 这是输出:
INFO [STDOUT] 186879 [http-0.0.0.0-8080-1] 调试 org.springframework.security.web.FilterChainProxy - 候选人是:'/myUrl';模式是 /myUrl;匹配=真
INFO [STDOUT] 186879 [http-0.0.0.0-8080-1] 调试 org.springframework.security.web.FilterChainProxy - /myUrl?param=value 有一个空的过滤器列表
我还尝试删除没有参数的 url 规则。然后,过滤器选择/** 模式并要求用户登录,而不是让我的带有参数的url 规则起作用。
输出是:
INFO [STDOUT] 73066 [http-0.0.0.0-8080-1] 调试 org.springframework.security.web.FilterChainProxy - 候选人是:'/myUrl';模式是 /**;匹配=真
INFO [STDOUT] 73068 [http-0.0.0.0-8080-1] 调试 org.springframework.security.web.FilterChainProxy - /myUrl?param=value 位于附加过滤器链中第 8 位的第 1 位;触发过滤器:'SecurityContextPersistenceFilter'
该应用程序是用 Java 1.6 编写的,使用 Spring v3.0 并部署在 Linux 机器上的 JBoss v5.1.0-GA 上。我不知道为什么过滤器会按照我描述的方式运行。非常感谢您的帮助和建议。
编辑:
作为结论,我观察到 /myUrl?param=value 过滤器从未应用 - 好像 security-context.xml 中的条目被忽略了。这符合我到目前为止观察到的行为。我还尝试用access="permitAll" 替换filters="none",切换到正则表达式(并相应地更改模式 - 例如/myUrl?param=value 变为\A/myUrl\?param=value\Z)并且在所有变体中我得到的行为都是相同的。
编辑 2:
这里描述的问题实际上是无效的。造成这种情况的原因如下:由于内部库冲突和不兼容,存在问题的项目排除了一些 spring 包,而整个设置以某种方式工作。我从来没有意识到这一点,实际上这种不纯的配置使整个问题过时了。具体原因是 isAuthenticated() 和 isAnonymous() 方法的实现没有按预期工作,因此这里提供的任何建议都不起作用。
【问题讨论】:
标签: java spring spring-security