带有SpringSecurity的JSF2:处理@Secured-Annotation的AccessDeniedException

时间:2013-10-23 08:08:40

标签: spring jsf jsf-2 spring-security

我在Spring 3.2.2和Majorra 2.1.25中使用Spring-Security 3.1.3。我不使用托管bean,但使用SpringBeanFacesELResolver。所以基本上,我使用spring来做所有事情。

我使用以下

<http auto-config="true">
    <form-login login-page="/components/public/login.jsf" authentication-failure-handler-ref="customAuthenticationFailureHandler" />
    <intercept-url pattern="/components/admin/**" access="ROLE_ADMIN" />
    <intercept-url pattern="/components/secured/**" access="ROLE_USER,ROLE_ADMIN" />
    <intercept-url pattern="/**" />
    <session-management>
        <concurrency-control max-sessions="1" expired-url="/components/public/sessionExpired.jsf" />
    </session-management>
    <access-denied-handler ref="customAccessDeniedHandler" />
</http>

作为indended工作,例如在访问安全页面时,用户被引导到登录,并且在登录之后他被带到所请求的页面。如果他试图访问管理员页面,但只有ROLE_USER,则我的customAccessDeniedHandler会将他定向到访问被拒绝的页面

到目前为止一切顺利。现在的问题如下: 我在方法上使用@Secured({ "ROLE_ADMIN" })。如果权限不足的用户访问此方法,则抛出AccessDeniedException,这正是我想要的。 但是:我的customAccessDeniedHandler未被调用!那是为什么?

更多信息:该方法作为AJAX调用的一部分被调用,我想使用我的处理程序将FacesMessage设置为反馈。我如何集中做到这一点?我很确定我可以围绕这个包装另一个方法并使用try-catch自己捕获AccessDeniedException。但是,为每个必须保护的方法执行此操作只会使用大量不必要的try-catch方法使我的代码膨胀。我如何集中处理异常?

1 个答案:

答案 0 :(得分:1)

我现在找到了解决方案。我使用Spring-AOP并将所有使用@Secured

注释的方法“绑定”在一个方面
<!-- aspect configuration -->
<aop:config>
    <aop:aspect id="securedAspect" ref="securityFeedbackAspect">
        <aop:around pointcut="@annotation(org.springframework.security.access.annotation.Secured)" method="handleSecuredAnnotations" />
    </aop:aspect>
</aop:config>

方面看起来像这样

@Service
public class SecurityFeedbackAspect {
    public Object handleSecuredAnnotations(final ProceedingJoinPoint pjp) throws Throwable {
        try {
            return pjp.proceed();
         } catch (AccessDeniedException e) {
            // log + set feedback for user here
         }
    }
}

希望有一天能帮到任何人。一个附加信息:不知何故我无法使用仅注释配置,因为@Secured-check将始终首先被调用,而我的方面只有在Spring-Security-Logic没有抛出异常时才会运行。我最终使用XML配置,这似乎总是先行,因为我找不到其他方式(即使使用@Order)