【问题标题】:Spring Boot Rest Controller - Is it possible to use a custom annotation to filter the request before processing it?Spring Boot Rest Controller - 是否可以在处理请求之前使用自定义注释来过滤请求?
【发布时间】:2021-01-26 05:47:10
【问题描述】:

我的应用程序中有许多控制器,并且希望能够注释控制器中的每个方法以表示访问该请求所需的权限级别。

举例

@RestController
class MyController {

    @Permission("MyC_R")
    @RequestMapping(value = "/list", produces = "application/json" method = RequestMethod.GET)
    public ResponseEntity<String> list(final HttpServletRequest req) throws UnsupportedEncodingException {
        ... fluff omitted for brevity



        return new ResponseEntity(body, rh, hs);
    }
}

我们正在使用包含用户权限的 JWT 令牌。我们希望能够将该参数MyC_R 传递给@Permission 注释-(意思是MyController/Read),然后检查该用户是否在其JWT 中具有权限。我已经有一个类可以提取它并检查用户权限 - 我只需要一种在请求之前调用它的方法,这样我就可以在发生这种情况时将 401 UNAUTHORIZED 标头返回到前端。

我研究过使用 AOP,但这似乎更全面地涵盖了控制器。我需要能够使用特定的 /per-controller-per-method/ 参数来应用它。

注释会在之前得到处理吗?如果在注解中权限检查失败,是否可以在不进入方法的情况下向前端发送响应?

【问题讨论】:

  • 当然,这是可能的,但是 Spring Security 已经完全按照您的要求使用 @PreAuthorize(和 @PostAuthorize)
  • 我们已经对此进行了调查 - 但它没有提供我们想要实施的必要措施

标签: spring spring-boot annotations spring-restcontroller


【解决方案1】:

您可以而且应该使用 AOP。您绝对可以将参数传递给您的注释以设置每个方法的权限级别。

如下定义一个接口:

@Retention(...)
@Target(ElementType.METHOD)
public @interface Permission {
   String permissionLevel();
}

然后定义你的实现

//This code gets executed before the controller code.
@Around("@annotation(...Permission)")
public Object authorizeRequest(ProceedingJoinPoint joinPoint) throws Throwable {

 try{
   MethodSignature methodSignature = (MethodSignature) jp.getSignature();
   Class<?> class = methodSignature.getDeclaringType();
   Method method = class.getDeclaredMethod(methodSignature.getName(),methodSignature.getParameterTypes());
   Permission yourCustomAnnotation = method.getAnnotation(Permission.class);
   String permissionLevel = yourCustomAnnotation.permissionLevel();

   //Do your filtering based on the parameter declared per controller

   if(user has permission) {
     // Execution continues to controller
     joinPoint.proceed();
   } else {
     //Return 401 to user

   }
 }catch(Exception exception) {
 }
    
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-02
    • 2018-12-11
    • 2011-02-17
    • 2016-01-27
    • 1970-01-01
    • 2019-12-10
    • 2018-02-28
    • 2011-07-29
    相关资源
    最近更新 更多