在ASP.NET Core中,从Cookie而不是标题中读取JWT令牌

Afs*_*bbi 6 c# authentication cookies jwt asp.net-core

我正在将ASP.NET Web API 4.6 OWIN应用程序移植到ASP.NET Core 2.1。该应用程序基于JWT令牌运行。但是令牌通过cookie而不是标头传递。我不确定为什么不使用标题,这只是我必须处理的情况。

考虑到身份验证不是通过cookie完成的。cookie仅用作传输介质。在旧版应用程序CookieOAuthBearerProvider中用于JWT从cookie中提取令牌。配置代码如下所示:

    app.UseJwtBearerAuthentication(
        new JwtBearerAuthenticationOptions
        {
            AuthenticationMode = AuthenticationMode.Active,
            AllowedAudiences = new[] { audienceId },
            IssuerSecurityTokenProviders = new IIssuerSecurityTokenProvider[]
            {
                new SymmetricKeyIssuerSecurityTokenProvider(issuer, audienceSecret)
            },
            Provider = new CookieOAuthBearerProvider("token")
        });
}
Run Code Online (Sandbox Code Playgroud)

CookieOAuthBearerProvider 类的源代码如下:

public class CookieOAuthBearerProvider : OAuthBearerAuthenticationProvider
{
    readonly string _name;
    public CookieOAuthBearerProvider(string name)
    {
        _name = name;
    }

    public override Task RequestToken(OAuthRequestTokenContext context)
    {
        var value = context.Request.Cookies[_name];

        if (!string.IsNullOrEmpty(value))
        {
            context.Token = value;
        }

        return Task.FromResult<object>(null);
    }
Run Code Online (Sandbox Code Playgroud)

这里将更详细地讨论此解决方案。

现在,我需要为ASP.NET Core实现类似的解决方案。问题是UseJwtBearerAuthentication不再存在,ASP.NET Core而且我不知道如何引入自定义AuthenticationProvider。

任何帮助都受到高度赞赏。

更新:一种解决方案试图通过自己的代码来验证JWT。这不是我所需要的。我只是在寻找一种方法,将接收自cookie的令牌传递给标头阅读器。

Kir*_*kin 10

在ASP.NET Core 2.0中,对身份验证系统进行了一些大修。UseJwtBearerAuthenticationASP.NET Core 2.0+ 不是使用中间件,而是使用DI进行配置。例如,这看起来像这样:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => {
            // ...
        });
}
Run Code Online (Sandbox Code Playgroud)

有了这种方式,下一个问题将是:我们如何指示JwtBearer身份验证过程使用此新系统查看cookie?

options传递给该对象的对象AddJwtBearer包含Events其自己的属性,该属性使您可以自定义过程的各个部分。使用OnMessageReceived,您可以实现所需的内容:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => {
            options.Events = new JwtBearerEvents
            {
                OnMessageReceived = context =>
                {
                    context.Token = context.Request.Cookies["CookieName"];
                    return Task.CompletedTask;
                }
            };
        });
}
Run Code Online (Sandbox Code Playgroud)

通过设置context.Token,您可以告诉JwtBearer进程您已经自己提取了令牌。

是一个有用的迁移文档,它详细说明了身份验证更改。