2012-09-03 27 views
1

我對AOP有點新,並對我面臨的問題感到困惑。我有註釋@AuthorizeUser,它對錶示層上的方法起作用。我需要檢查用戶是否有權執行該方法。下面是AuthorizeUserAspect代碼:
Spring-AOP之前的條件行爲建議

@Aspect 
public class AuthorizeUserAspect { 
    @AuthoWired 
    private UserService service; 

    @Before(value = "@annotation(com.company.annotation.AuthorizeUser)") 
    public void isAuthorized(JoinPoint jp) { 
     // Check if the user has permission or not 
     // executing some Service Layer services and 
     // Persistence Layer, corresponding to that 
     service.checkUser(); 

     // Is there a way I can make this method Conditional. something like: 
     if (/* User has permission */) { 
      // do nothing, so the method will be executed after this 
     } 
     else { 
      // 1) Prevent the Method to be executed [and/or] 
      // 2) Pass some Parameters to the method for checking [and/or] 
      // 3) Execute another method on that class [e.g showAccessDenied()] 
     } 
    } 
} 

它類似於這個問題Spring MVC + Before Advice check security一點點。但它建議返回一些字符串(即「不好」)。在我的應用程序中有兩種類型的UI(Struts和Jersey),所以會有兩種類型的返回類型(分別爲StringResponse)。所以我想這可能不是最好的辦法。

如果您能向我展示解決方法,我將非常高興。
這是一個很好的方法嗎?

回答

2

首先,你看過Spring Security?它是完全聲明性的,不需要你自己編寫方面。如果用戶未通過身份驗證或者沒有所需的權限,則通過拋出異常來保證方法的安全。

關於你的問題有兩個不同的返回類型:

第一種選擇:創建兩種不同意見的,具體到方法的返回類型:

@Before("@annotation(com.company.annotation.AuthorizeUser) && execution(String *.*(..))") 
public void isAuthorizedString(JoinPoint jp) { 
    ... 
} 

@Before("@annotation(com.company.annotation.AuthorizeUser) && execution(Response *.*(..))") 
public void isAuthorizedResponse(JoinPoint jp) { 
    ... 
} 

第二個選項:找出回報通過反射建議的方法的類型,並返回一個不同的值,基於此:

@Before("@annotation(com.company.annotation.AuthorizeUser") 
public void isAuthorized(JoinPoint jp) { 
    Class<?> returnType = ((MethodSignature)jp.getStaticPart() 
      .getSignature()).getReturnType(); 
    if(returnType == String.class) 
     ... 
    else 
     ... 
} 
+0

感謝您的答覆和不,我沒有考慮Spring Security。我會檢查出來的。在上面代碼的'else'塊中提到的第三個選項呢?可能嗎?或者任何關於這個問題的pro/con? – Khosrow

+1

這當然是可能的。你可以使用'jp.getThis()'獲得正在執行的對象。當然,現在你必須知道你必須將它投入哪個類(或使用反射來調用該方法)。但我會推薦更簡單的方法:使用'@ Around'通知來引發異常,並設計客戶端類來捕獲該異常並顯式調用showAccessDenied()。 – rolve