2013-10-23 27 views
0

我在Spring 3.2.2和Majorra 2.1.25中使用Spring-Security 3.1.3。我不使用托管bean,但使用SpringBeanFacesELResolver。所以基本上,我用春天来做一切事情。带SpringSecurity的JSF2:处理@ Secured-Annotation的AccessDeniedException

我使用下面

<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方法。我如何集中处理异常?

回答

0

我现在找到了解决方案。我使用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检查将始终首先被调用,而且只有在Spring-Security-Logic没有抛出异常的情况下,我的方面才会运行。我结束了使用XML配置,这似乎总是先走,因为我发现没有其他的方式(即使@Order)