aspnet核心jwt令牌作为get param

p.d*_*ich 10 c# jwt asp.net-core asp.net-core-2.0

我正在开发一个aspnet core 2 web api项目,主要消费者是一个vue web应用程序.

Api使用jwt令牌作为身份验证方法,一切正常.

现在我已经提出了所有代码来管理数据库中的图像存储和检索,但我在从db中获取图像时遇到了问题.

所有路由(登录除外)都在身份验证之后,因此要检索图像,我在请求标头中有通过令牌(通常)

这使我无法使用图像源标签实际显示图像,如

<img src="/api/images/27" />
Run Code Online (Sandbox Code Playgroud)

相反,我必须编写一些javascript代码来请求图像并将内容放在图像标记中,例如

// extracted from vue code (not my code, i'm the backend guy)
getImage() {
    this.$http.get('api/images/27', {headers: {'Authorization': 'Bearer ' + this.token},responseType: 'blob'})
    .then(response => {
        return response.blob()
    }).then(blob => { 
        this.photoUrl = URL.createObjectURL(blob)
    })
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,但它在某种程度上是一种不必要的复杂性.

我在AspNet Core Identity中看到了这一点

或者,您可以从其他位置获取令牌,例如不同的标头,甚至是cookie.在这种情况下,处理程序将使用提供的令牌进行所有进一步处理

(摘自该文章由安德烈锁博客),你还可以看到检查ASPNET核心安全代码,它说:

为应用程序提供从不同位置查找,调整或拒绝令牌的机会

但我找不到任何关于如何使用此功能并传递自定义令牌的示例.

所以,我的问题是:有没有人知道如何将自定义令牌(可能从get参数读取)传递给身份提供者(甚至可能只针对某些已定义的路由)?


感谢serpent5的正确答案.

如果有人感兴趣,从url param读取令牌并将其传递给验证的完整代码如下

service.AddAuthentication(...)
    .AddJwtBearer(options =>
        // ...
        options.Events = new JwtBearerEvents
        {
            OnMessageReceived = ctx =>
            {
                // replace "token" with whatever your param name is
                if (ctx.Request.Method.Equals("GET") && ctx.Request.Query.ContainsKey("token"))
                    ctx.Token = ctx.Request.Query["token"];
                return Task.CompletedTask;
            }
        };
    });
Run Code Online (Sandbox Code Playgroud)

Kir*_*kin 10

这可以使用JwtBearerEvents连接到JwtBearerOptions提供的实例的连接来处理AddJwtBearer.具体来说,OnMessageReceived可以实现一个事件来提供令牌本身.这是一个例子:

services.AddAuthentication(...)
    .AddJwtBearer(jwtBearerOptions =>
    {
        // ...

        jwtBearerOptions.Events = new JwtBearerEvents
        {
            OnMessageReceived = ctx =>
            {
                // Access ctx.Request here for the query-string, route, etc.
                ctx.Token = "";
                return Task.CompletedTask;
            }
        };
    })
Run Code Online (Sandbox Code Playgroud)

您可以在源代码中看到它的使用方式:

// event can set the token
await Events.MessageReceived(messageReceivedContext);

// ...

// If application retrieved token from somewhere else, use that.
token = messageReceivedContext.Token;
Run Code Online (Sandbox Code Playgroud)