通常,您可以定义一些intercept-url模式来配置对具有spring security
的页面的访问<http use-expressions="true">
<intercept-url pattern="/**/secure/**" access="hasRole('ROLE_SECURE_USER')" />
...
</http>
我们现在有的网页包含之前未知的网址。但是我们可以编写一段代码来决定是否应该保护特定页面,即如果页面必须受到保护,我们可以提供返回true的服务。所以我们想要做的就是这样:
<http use-expressions="true">
<intercept decide="@service.mustProtect()" access="hasRole('ROLE_SECURE_USER')" />
...
</http>
如何通过Spring实现这一目标?我们必须编写自定义过滤器吗?你会如何实现这样的过滤器?
答案 0 :(得分:2)
实际上,通过在FilterSecurityInterceptor
之前注入自定义过滤器来解决我们的问题非常容易。然后,您可以在过滤器的AccessDeniedException
方法中抛出doFilter
以触发身份验证。
Spring安全配置:
<http use-expressions="true">
<custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="accessFilter"/>
...
</http>
<beans:bean id="accessFilter" class="xyz.AccessFilter" />
过滤器:
public class AccessFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!currentUserCanAccessPage(request)) {
throw new AccessDeniedException();
}
chain.doFilter(request,response)
}
private boolean currentUserCanAccessPage(ServletRequest request) {
//implement
}
}
答案 1 :(得分:0)
<intercept-url>
标记所做的只是填充一个存储库(名为SecurityMetadataSource
),其中RequestMatcher
被映射到ConfigAttribute
s。 RequestMatcher
是基于pattern
属性生成的,而ConfigAttribute
只是保存access
属性中指定的字符串。
当传入请求到达FilterSecurityInterceptor
过滤器时,它将遍历这些映射列表以查找第一个条目,其中RequestMatcher
表示匹配,以确定访问类型它必须强制执行的限制(由映射的ConfigAttribute
描述)。
现在,如果你可以将自己的RequestMatcher
实现放到这个地图上,你的要求基本上就会得到解决。难点在于命名空间配置不适合此用例,它只能将pattern
属性解释为AntPathRequestMatcher
或RegexRequestMatcher
。
这意味着您必须在bean级别配置安全性基础结构,因为<http>
元素创建了自己的FilterSecurityInterceptor
,无法替换。
在this article中,您可以找到有关如何编写此类手动安全配置的极大帮助。