2010-04-01 5 views
13

Tôi muốn triển khai bảo mật khai báo với Spring/AOP và chú thích. Như bạn thấy trong ví dụ mã tiếp theo, tôi có các chú thích bị giới hạn với paramter "allowedRoles" để xác định ai được phép thực hiện một phương thức được đề xuất.Spring AOP: cách nhận các chú thích của phương pháp được đề xuất

@Restricted(allowedRoles="jira-administrators") 
     public void setPassword(...) throws UserMgmtException {    
       // set password code 
       ... 
     } 

Bây giờ, vấn đề là trong Lời khuyên của tôi, tôi không có quyền truy cập vào các chú thích định nghĩa:

public Object checkPermission(ProceedingJoinPoint pjp) throws Throwable { 

    Signature signature = pjp.getSignature(); 
    System.out.println("Allowed:" + rolesAllowedForJoinPoint(pjp)); 
      ... 
} 

private Restricted rolesAllowedForJoinPoint(ProceedingJoinPoint thisJoinPoint) 
     { 
      MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature(); 
      Method targetMethod = methodSignature.getMethod(); 

      return targetMethod.getAnnotation(Restricted.class); 
     } 

Các phương pháp trên luôn luôn trả về null (không có chú thích tìm thấy ở tất cả). Có một giải pháp đơn giản cho việc này không?

Tôi đã đọc điều gì đó về việc sử dụng tác nhân AspectJ nhưng tôi không muốn sử dụng tác nhân này.

Trả lời

13

Tôi giả định @Restricted là chú thích của bạn. Nếu đúng như vậy, hãy đảm bảo bạn có:

@Retention(RetentionPolicy.RUNTIME) 

trong định nghĩa chú thích của bạn. Điều này có nghĩa là chú thích được giữ lại trong thời gian chạy.

+0

Cảm ơn rất nhiều, đó là lý do. – hugri

2

Tại sao bạn không chỉ sử dụng Spring Security? Đó là một tóm tắt để thực hiện và sử dụng, tôi không thực sự nhìn thấy điểm trong lãng phí thời gian tái phát minh bánh xe.

+0

Cảm ơn, tôi sẽ xem xét nó ngay – hugri

4

Ngay cả sau khi thay đổi chính sách duy trì như Bozho đề cập cuộc gọi này để có được lợi nhuận chú thích là null:

targetMethod.getAnnotation(Restricted.class); 

Những gì tôi thấy là bạn phải để ràng buộc các chú thích. Với giao diện được khai báo như thế này:

@Retention(RetentionPolicy.RUNTIME) 
public @interface Restricted { 
    String[] allowedRoles(); 
    } 

Lời khuyên sẽ cần phải được khai báo như thế này:

 @Before("@annotation(restrictedAnnotation)") 
     public Object processRequest(final ProceedingJoinPoint pjp, Restricted restrictedAnnotation) throws Throwable { 
        String[] roles = restrictedAnnotation.allowedRoles(); 
        System.out.println("Allowed:" + roles); 
     } 

Điều này không được ràng buộc chú thích để các tham số trong các phương pháp chữ ký, restrictedAnnotation. Phần tôi không chắc chắn về cách nó nhận được loại chú thích, nó dường như được dựa trên tham số. Và một khi bạn có chú thích, bạn có thể nhận được các giá trị.

2

Whith Spring AOP nếu bạn có tình huống như MyManagerImpl implements MyManager, phím tắt được áp dụng cho phương pháp interface để MethodSignature mô tả phương pháp được xác định trên MyManager không có chú thích nào. cách duy nhất tôi tìm thấy để sửa lỗi này là kiểm tra lớp của đối tượng jp.getTarget() và truy xuất phương thức tương ứng.

27

Đối với bất kỳ ai vẫn gặp sự cố sau khi thay đổi lưu giữ chú thích thành Thời gian chạy, bạn có thể gặp vấn đề tương tự như vậy: getMethod() trả về phương thức giao diện thay vì lớp triển khai. Vì vậy, nếu bạn có chú thích của bạn trong lớp thì getAnnotations tự nhiên() trên phương thức giao diện trả về null.

Các giải pháp sau đây giải quyết vấn đề này:

final String methodName = pjp.getSignature().getName(); 
final MethodSignature methodSignature = (MethodSignature)pjp.getSignature(); 
Method method = methodSignature.getMethod(); 
if (method.getDeclaringClass().isInterface()) { 
    method = pjp.getTarget().getClass().getDeclaredMethod(methodName, method.getParameterTypes());  
} 

và nếu bạn thích, bạn có tùy chọn xử lý chú thích giao diện ở đây quá.

Một số ý kiến ​​nhiều hơn có sẵn ở đây: getting template method instance from ProceedingJoinPoint

Oleg

+0

Xin chào, cảm ơn rất nhiều từ tương lai! –