2013-10-23 58 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)