1

我正在使用 Spring 3.1.0,并且遇到了一种我会归类为错误的行为。然而,我相信有更大的可能性是我的错。非常感谢任何帮助。

我已经成功地遵循了使用 spring security 3 动态创建 <intercept-url pattern>的建议。所以我已经成功地配置了一个 http 命名空间来使用我自己的 securityMetadataSource。

请注意,我知道不建议这样做。但事实上我没有让它按预期工作,这让我觉得我错过了一些重要的东西。

上面链接线程中所述,我设法使如下配置正常工作:

<http>
  <form-login login-page="/login" 
    default-target-url="/welcome"
    always-use-default-target="false" 
    authentication-failure-url="/login?error=1" 
    />
  <logout logout-url="/logout.secure" logout-success-url="/" />
  <http-basic/>
  <custom-filter ref="myFilterSecurityInterceptor"
    before="FILTER_SECURITY_INTERCEPTOR" />
</http> 

因此,myFilterSecurityInterceptor 使用 mySecurityMetadataSource,我在其中定义 SecurityConfig 实例,例如“ROLE_ADMIN”、“IS_AUTHENTICATED_FULLY”等;和 AntPathRequestMatcher 实例来检查。它有效:如果用户没有给定的角色,则拒绝访问所需的路径。

问题在于安全标签库。

根据有关安全标签库的 Spring 文档(此处),使用<security:authorize>标签

您的应用程序上下文中还必须有一个 WebInvocationPrivilegeEvaluator 实例。如果您正在使用命名空间,则会自动注册一个。

在第一次调用时<security:authorize url="" >...</security:authorize>抛出异常,因为似乎没有WebSecurityExpressionHandler找到实现 bean。实际上,我的 myFilterSecurityInterceptor用途mySecurityMetadataSource是实现FilterInvocationSecurityMetadataSource. 所以我的过滤器实现不处理表达式。在我的配置中,我没有声明这样一个 bean。实际上,我认为不需要表达式处理,因为我没有在<http>声明中询问任何内容,并且如上面的文档所述:

第一种方法使用标签的访问属性中指定的网络安全表达式。表达式评估将委托给应用程序上下文中定义的 SecurityExpressionHandler(您应该在命名空间配置中启用 Web 表达式以确保此服务可用)。[...] 此标签还可以在另一种模式下运行,该模式允许您将特定 URL 定义为属性。

所以我认为不需要表达式处理,因为我使用了第二种使用<security:authorize>: url方法而不是访问方法的方法。

无论如何,我可以避免将以下属性添加到<http>声明中的异常:

use-expressions="true"

在对我的配置进行了后一种改进后,我得到:1)我的基于角色的授权(在mySecurityMetadataSource简单字符串中实现并检查 url 匹配为“ROLE_ADMIN”或“IS_AUTHENTICATED_FULLY”)正常工作,如果用户拒绝访问 url未获得所需的授权;2)<security:authorize>标签找不到声明的拦截器(<http>似乎忽略了自定义过滤器设置)所以每个链接都会显示,无论用户扮演哪个角色。

所以我的问题是:是否可以(轻松)将<security:authorize>标签与您自己的 SecurityMetadataSource 混合?

提前感谢您的任何帮助或提示。乔亚历山德罗

4

0 回答 0