基于Quarkus注解的拦截器,带有非可选参数

问题描述

根据所问的问题数量,这似乎是一个热门话题,但我尚未找到我正在寻找的答案。我想在Quarkus应用程序中实现一个简单的授权服务,但是我似乎要一遍又一遍地重复代码。

基本上,我从Authorization Http标头中获取JWT,并检查其中提供的角色是否足以访问我的端点:

public void someApiCall(@Context HttpHeaders headers) {
    authService.validate(ApiToken.SOME_API_CALL,headers); // Throws an exception when unauthorized
    
    //…
}

现在,我认为这看起来很笨拙,我不喜欢每个Http终结点都需要的其他参数。我已经对AOP进行了一些研究,并且知道如何添加一个拦截器,该拦截器可以通过将应用于我的方法的注释来验证Http标头:

@Authorize
public void someApiCall(/*…*/) { /*…*/ }

问题是,我不知道如何将参数传递到此批注中以指定所需的角色。我想要这样的东西:

@Authorize(UserRole.SYSADMIN)

这似乎很简单,但我无法弄清楚。在下面,您将找到拦截器和注释类(当然,缺少所需的角色):

Authorize.java

@Retention(value=RUNTIME)
@Target(value=METHOD)
public @interface Authorize {}

AuthorizeInterceptor.java

@Interceptor
@Priority(3000)
@Authorize
public class AuthorizeInterceptor {

    @Inject
    AuthorizationService authService;

    @AroundInvoke
    public void validateRole(InvokationContext ctx) {
        authService.validate(ApiToken.ALL,((RestEndpoint)ctx.getTarget()).getHttpHeaders());
    }
}

RestEndpoint.java

public class RestEndpoint {

    @Context
    HttpHeaders headers;

    public HttpHeaders getHttpHeaders() { return headers; }
}

SomeResource.java

public class SomeResource extends RestEndpoint {

    @GET
    @Authorize
    public Object someApiCall() {
        /* do code directly */
    }
}

因此,总而言之,在我写@Authorize的地方,我想拥有@Authorize(UserRole.SOME_ROLE)

谢谢!

解决方法

所以,我设法弄清楚了。事实证明,这并不难,我只是不知道在哪里看。

以下是修改后的类:

Authorize.java

@InterceptorBinding
@Retention(RUNTIME)
@Target({TYPE,METHOD})
public @interface Authorize {
    // Nonbinding is very important. It makes the interceptor fire regardless of the value
    @Nonbinding ApiToken value();
}

AuthorizeInterceptor.java

@Interceptor
@Priority(3000)
@Authorize(ApiToken.NULL)
public class AuthorizeInterceptor {
    /* fields */

    public Object validate(InvokationContext ctx) throws Exception {
        authService.validate(/* stays the same */);
        return ctx.proceed();
    }
}

SomeResource.java

public class SomeResource {
    @GET
    @Authorize(ApiToken.SOME_API_CALL)
    public Object someApiCall() { /* implementation */ }
}

正如Turing85指出的那样,JavaEE中已经存在类似的API,该API以相同的方式实现授权功能。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...