对于我们当前的项目,我们正在集成JSF和Spring Framework。我想使用Spring Security来处理身份验证和授权。到目前为止,我已经实现了一个正常运行的自定义PasswordEncoder
和AccessDecisionVoter
。现在我正在尝试使用@Secured
注释(以及其他注释)来保护方法,但我不能像我期望的那样使用它。
似乎@Secured
注释仅适用于直接从JSF层调用的bean方法。这是一个简化的例子:
@Named("foobarBean")
@Scope("access")
public class FoobarBean
{
@Secured("PERMISSION_TWO")
public void dummy()
{
}
@Secured("PERMISSION_ONE")
public String save()
{
dummy();
}
}
方法save()从JSF层调用,如下所示:
<h:commandButton id="save" action="#{foobarBean.save}" />
然后我们要求AccessDecisionVoter
对PERMISSION_ONE进行投票,而对PERMISSION_TWO 不进行投票。这是按照设计工作(我希望不是)或者我做错了什么(可能是什么?)。
我会发布更多代码或配置,但我不确定哪个部分是相关的,我不想让这篇文章混乱。
答案 0 :(得分:2)
这是代理AOP的一个简单问题!如果您使用代理AOP进行安全性,则代理只能拦截通过代理的密码。如果一个方法直接调用同一个bean的另一个方法,则没有可以拦截此调用的代理。 - 这就是为什么只考虑save()
的安全注释的原因。
一种解决方案是使用AspectJ AOP而不是Proxy AOP。 (它也受到Spring(安全)的支持。)
答案 1 :(得分:1)
是的,这就是AccessDecisionVoter
的工作原理。它需要资源上允许的所有角色(在您的情况下为方法),并从当前经过身份验证的用户角色中投票选出这些角色。如果匹配角色,则仅授予权限。
在您的情况下,为save
方法定义的唯一角色是PERMISSION_ONE
,因此安全系统将仅检查此角色。如果登录用户具有该角色,则将执行此方法。