3

通常,您定义一些拦截 URL 模式来配置对具有弹簧安全性的页面的访问

<http use-expressions="true">
    <intercept-url pattern="/**/secure/**" access="hasRole('ROLE_SECURE_USER')" />
    ...
</http>

我们现在有事先不知道 url 的页面。但是我们可以编写一段代码来决定是否应该保护特定页面,即我们可以提供一个服务,如果该页面必须受到保护,则返回true。所以我们想做的是这样的:

<http use-expressions="true">
    <intercept decide="@service.mustProtect()" access="hasRole('ROLE_SECURE_USER')" />
    ...
</http>

Spring如何实现这一点?我们必须编写自定义过滤器吗?你将如何实现这样的过滤器?

4

2 回答 2

2

实际上,通过在FilterSecurityInterceptor. 然后,您可以AccessDeniedException在过滤器的doFilter方法中抛出一个来触发身份验证。

弹簧安全配置:

<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
    }
}
于 2013-08-21T15:29:05.953 回答
0

标签所做的<intercept-url>只是填充一个存储库(称为SecurityMetadataSource),其中RequestMatchers 映射到ConfigAttributes。RequestMatchers 是根据pattern属性生成的,而ConfigAttributes 只是保存access属性中指定的字符串。

当传入请求命中FilterSecurityInterceptor过滤器时,它将遍历这些映射的列表以找到第一个条目,其中RequestMatcher表示匹配,以确定它必须强制执行的访问限制类型(由 mapped 描述ConfigAttribute)。

现在,如果你能把你自己的RequestMatcher实现放到这张地图上,你的需求就基本解决了。困难在于命名空间配置不适合这个用例,它只能将pattern属性解释为 asAntPathRequestMatcher或 as RegexRequestMatcher

这意味着您必须在 bean 级别配置安全基础结构,因为<http>元素会创建自己的FilterSecurityInterceptor无法替换的元素。

本文中,您可以在如何编写这种手动安全配置方面找到很大的帮助。

于 2013-08-21T10:53:09.917 回答