我正在使用 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 混合?
提前感谢您的任何帮助或提示。乔亚历山德罗