如何从 micronaut 上的 MethodInterpcetor 获取授权标头? [英] How to get Authorization header from an MethodInterpcetor on micronaut?

查看:74
本文介绍了如何从 micronaut 上的 MethodInterpcetor 获取授权标头?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此之前,我尝试了这两种解决方案,但对我不起作用
Micronaut 中 javax.ws.rs NameBinding 的等价物?
https://blogs.ashrithgn.com/custom-annotation-to-handle-authorisation-in-micronaut-aop-tutorial/

Before everything I tried this two solution but didn't work for me
Equivalent of javax.ws.rs NameBinding in Micronaut?
https://blogs.ashrithgn.com/custom-annotation-to-handle-authorisation-in-micronaut-aop-tutorial/

在我的应用程序中,我必须在 Authorization 标头中获取一个字符串,然后从 base64 解码它,然后 json 将其转换为 POJO.当然,字符串是一个 jwt,我需要解码 json 的公共部分以从字段中获取数据.
从技术上讲,客户端会将标头转发给我以获取它,对其进行解码并提取数据.(这是非常糟糕的做法,但这是我必须做的).

In my application I have to get a string in the Authorization header and then decode it from base64 and the json transform it into a POJO. Certainly the string is a jwt and I need to decode the public part of the json to get a data from a field.
Technically speaking a client will forward the header to me to take it, decode it and extract the data. (It's very bad practice but that's what I have to do).

为此,我使用 micronaut 2.4.1,这是我的代码:

For this I am using micronaut 2.4.1 and this is my code:

拦截器:

public class HeadInterceptor implements MethodInterceptor<Object, Object> {
    @SneakyThrows
    @Override
    public Object intercept(MethodInvocationContext<Object, Object> context) {

        Request request = (Request) context.getParameterValueMap().get("request");
        // Where do i get Authorization header?
        // i.e String token = (String) context.getParameterValueMap().get("Authorization");
        String token = "eyJhdWQiOiJ0ZXN0IiwiaXNzIjoidGVzdCIsInN1YiI6InRlc3QiLCJleHAiOjExMTExMTEsImlhdCI6MTExMTExMTEsImRhdGEiOiJ0ZXN0In0=";

        ObjectMapper mapper = new ObjectMapper();
        Info info = mapper.readValue(new String(Base64.getDecoder().decode(token)), Info.class);
        request.setData(info.getSub().toUpperCase());

        return context.proceed();
    }
}

控制器:

@Controller("/main")
public class MainController {

    @Post
    @Head
    public Single<Response> index(@Body @Valid Request request) {
        return Single.just(
                Response.builder()
                        .message(String.format("%s-%s", request.getData(), request.getInfo()))
                        .build()
        );
    }
}

这是一个示例应用程序 https://github.com/j1cs/micronaut-jacksonxml-error
(忽略名称是其他问题)

Here's a sample app https://github.com/j1cs/micronaut-jacksonxml-error
(ignore the name is for other issue)

推荐答案

在您的实现中,标题无法在拦截器中显示,因为您的 index 方法没有将其作为参数接收.

In your implementation, the header cannot be shown in the interceptor because your index method doesn't receive it as a parameter.

因此,如果您将其添加为如下参数:

So, if you add it as a parameter as below:

...
@Post
@Head
public Single<Response> index(@Body @Valid Request request, @Header("Authorization") String authorizationHeader) {
    return Single.just(
            Response.builder()
                    .message(String.format("%s-%s", request.getData(), request.getInfo()))
                    .build()
    );
}
...

然后,您可以通过 getParameterValues()intercept 方法中检索它.基本上,这将是第二个参数.

Then, you can retrieve it in the intercept method via getParameterValues(). Basically, it will be the second argument.

...
@SneakyThrows
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
    ...
    String token = (String) context.getParameterValues()[1];
    ...
}
...

更新

由于您希望 Request 包含正文和标题,因此我稍微编辑了解决方案.基本上,标头作为成员变量添加到 Request 如下:

Update

Since you want your Request to contain both body and header, I edited the solution a bit. Basically, the header is added as a member variable to Request as below:

public class Request {
    @NotNull
    @NotBlank
    private String info;
    private String data;

    @Header("Authorization")
    String authorizationHeader;
} 

然后,在 Request 参数上使用 @RequestBean 而不是 @Body 注释:

Then, use @RequestBean rather than a @Body annotation on your Request parameter:

...
@Post
@Head
public Single<Response> index(@RequestBean @Valid Request request) {
    return Single.just(
            Response.builder()
                    .message(String.format("%s-%s", request.getData(), request.getInfo()))
                    .build()
    );
}
...

最后,您可以在 intercept() 方法中轻松访问标头,如下所示:

Finally, you can access the header easily in your intercept() method as follows:

@SneakyThrows
@Override
public Object intercept(MethodInvocationContext<Object, Object> context) {
    ...   
    Request request = (Request) context.getParameterValueMap().get("request");
    String token = request.authorizationHeader;
    ...
}

我为此更改创建了拉取请求此处,以便您可以检查它是如何工作的.

I created a pull request for this change here, so you can check how it works.

这篇关于如何从 micronaut 上的 MethodInterpcetor 获取授权标头?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆