根据 JAVA 中的方法和 class 访问自定义注释字段

Access Custom annotation fields according to method and class in JAVA

我必须根据允许访问的范围来授权请求​​。我有一个基于令牌的授权,returns 我是请求允许的范围。如果其中一个范围与我的 API 允许的范围匹配,那么我允许它访问 API 的内容。所以,我创建了一个自定义注释

 @Target(ElementType.METHOD)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Authorize{
 String[] scopes() default {""};
}

因此,在每个 API 中,我只是将注释放在方法上方,并将其与令牌授权返回的范围相匹配。

我的控制器1

@PostMapping("/insert")
@Authorize(scopes = {"read", "write"})
public HttpStatus create(){
 // insertion code
}

@GetMapping("/students")
@Authorize(scopes = {"foo", "bar"})
public List<Student> get(){
// Get Code
}

我的控制器2

@PostMapping("/insert")
@Authorize(scopes = {"read", "write"})
public HttpStatus create(){
 // insertion code
}

@GetMapping("/classes")
@Authorize(scopes = {"foo", "bar"})
public List<Class> get(){
// Get Code
}

我尝试访问范围并匹配的代码:

private void validateScope(String[] scopes){
// Here 'scopes' is a string list which token authorization returned.
  Method[] methods = GenericController.class.getMethods();
  for(Method m: methods){
    if(m.isAnnotationPresent(Authorize.class)){
       Authorize auth = m.getAnnotation(Authorize.class)
       for(String t: auth.scopes())
         System.out.println(t);
    }
  }
  // once I parse the corresponding scopes allowed by the API properly, then here I will match it with 'scopes' 
}

这只是打印出应用于 Class 的所有范围。而且,我还必须指定一个特定的控制器。我想让它通用

我怎样才能做到这一点?我想让调用变得通用,这样我就可以调用任何控制器,还可以从特定方法获取范围,而不是全部。我在想 Google 反射可能会有所帮助,但我不明白如何将它用于我的用例。

我已经尝试操纵 Is it possible to read the value of a annotation in java? 的所有答案,但其中 none 有效。任何线索将不胜感激。提前致谢

在我看来,授权是您 API 的一个横切关注点。您的要求是使用方面的最佳人选。我已经使用 Spring 方面来演示它是如何完成的。这不是一个有效的代码,但给出了总体思路:

  /**
  * Proxies a controller annotated with {@link Authorise} and checks if the requested scope
  * is in the list of allowed scopes.
  * @param pjp of type sometype
  * @throws {@link AuthorisationBusinessException} is the requested scope is not allowed.
  */
  @Around("@annotation("pathToAnnotation")")
  public Object authorisationAdvice(ProceedingJoinPoint pjp)
      throws Throwable {

    MethodSignature signature = (MethodSignature) pjp.getSignature();

    Authorize annotation = signature.getMethod().getAnnotation(Authorize.class);
    List<String> allowedScopes = annotation.scopes();

    Object arg = pjp.getArgs()[0];    //this will be the argument to your controller. Cast to to the appropriate type and get the requested scope from the token.

    // get the requested scope

   if(annotation.scopes().contains(requestedScope)) {
       return pjp.proceed(); 
   } else {
      //throw exception
   }
}

这个建议基本上是拦截任何用 @Authorise 注释的方法。一旦该方法被代理,您就拥有了允许的范围集,以及您所请求的范围。您现在可以添加任何您想要的检查。

您可以在此处阅读 Spring 方面的内容:https://docs.spring.io/spring/docs/2.5.x/reference/aop.html