13

我想用 Spring/AOP 和注释来实现声明式安全性。正如您在下一个代码示例中看到的那样,我有带有参数“allowedRoles”的受限注释,用于定义允许执行建议方法的人员。

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

现在,问题是在我的建议中我无法访问定义的注释:

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);
        }

上面的方法总是返回 null (根本没有找到注释)。有一个简单的解决方案吗?

我读过一些关于使用 AspectJ 代理的文章,但我不想使用这个代理。

4

5 回答 5

32

对于在将注释保留更改为运行时后仍有问题的人,您可能遇到了与我相同的问题:getMethod() 返回接口方法而不是实现类。因此,如果您在类中有注释,那么接口方法上的 getAnnotations() 自然会返回 null。

以下解决方案解决了这个问题:

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());    
}

如果你喜欢,你也可以在这里处理接口注释。

此处提供更多评论: 从 ProceedingJoinPoint 获取模板方法实例

奥列格

于 2011-03-09T00:42:41.763 回答
13

我假设@Restricted是你的注释。如果是这种情况,请确保您拥有:

@Retention(RetentionPolicy.RUNTIME)

在您的注释定义中。这意味着注释会在运行时保留。

于 2010-04-01T09:10:05.920 回答
5

即使在像 Bozho 提到的更改保留策略之后,获取注释的调用也会返回 null:

targetMethod.getAnnotation(Restricted.class);

我发现你必须绑定注释。鉴于接口声明如下:

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

该建议需要像这样声明:

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

这样做是将注解绑定到方法签名中的参数,restrictedAnnotation。我不确定的部分是它如何获取注释类型,它似乎是基于参数的。一旦有了注释,您就可以获得值。

于 2010-09-01T02:56:34.927 回答
2

如果您有类似MyManagerImpl implements MyManager切入点应用于interface方法的情况,那么使用 Spring AOP 来MethodSignature描述在该方法上定义的MyManager没有任何注释的方法。我发现解决此问题的唯一方法是检查jp.getTarget()对象的类并检索相应的方法。

于 2011-02-16T17:28:45.493 回答
2

你为什么不直接使用Spring Security?这是一个简单的实现和使用,我真的不明白浪费时间重新发明轮子的意义。

于 2010-04-01T09:13:45.667 回答