如何在控制器操作中访问JwtBearer身份验证处理程序配置?

时间:2019-08-14 17:46:52

标签: c# asp.net-core jwt jwt-auth

我有一个配置为使用JWT承载令牌进行身份验证的ASP.NET Core Web应用程序:

// Setup.cs
// ...
public void ConfigureServices(IServiceCollection services) {
    services
        .AddAuthentication()
        .AddJwtBearer(
            options =>
            {
                options.Authority = "https://known.authority.url";
            });
}
// ...

该应用具有控制器操作,可以在POST请求的正文中接收使用相同密钥信息签名的JWT。

// TokenController.cs
// ...
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> ActionAsync()
{
    using (var stream = new MemoryStream())
    using (var reader = new StreamReader(stream))
    {
        await Request.Body.CopyToAsync(stream);
        stream.Seek(0, SeekOrigin.Begin);

        var jwt = await reader.ReadToEndAsync();

        // ...
    }
    // ...
}
// ...

我想使用在承载令牌认证处理程序中配置的相同验证参数和签名密钥来验证在控制器操作中收到的JWT。 (理想情况下,无需复制控制器操作的配置。)

如何在控制器操作中访问身份验证处理程序的JwtBearerOptions Configuration属性?

我已经确认JwtBearerHandlerHttpContext.RequestServices中的注册服务,但是其Options属性始终是null

1 个答案:

答案 0 :(得分:0)

找到了答案:ASP.NET注册了一个IAuthenticationHandlerProvider服务,该服务可用于按其方案检索身份验证处理程序。

因此,在修改Startup.cs文件以包括JWT承载处理程序的身份验证方案之后:

// Startup.cs
// ...
public void ConfigureServices(IServiceCollection services)
{
    services
        .AddAuthentication()
        .AddJwtBearer(
            authenticationScheme: "MY_AUTH_SCHEME", // NEW
            options =>
            {
                options.Authority = "https://known.authority.url";
            });
}
// ...

使用身份验证处理程序提供程序服务及其GetHandlerAsync方法来获取处理程序及其选项:

// TokenController.cs
// ...
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> ActionAsync()
{
    // NEW
    var provider = HttpContext.RequestServices.GetService<IAuthenticationHandlerProvider>();

    // NEW
    var handler = await provider.GetHandlerAsync(HttpContext, "MY_AUTH_SCHEME") as
        AuthenticationHandler<JwtBearerOptions>;

    // NEW
    var jwtBearerOptions = handler.Options;

    using (var stream = new MemoryStream())
    using (var reader = new StreamReader(stream))
    {
        await Request.Body.CopyToAsync(stream);
        stream.Seek(0, SeekOrigin.Begin);

        var jwt = await reader.ReadToEndAsync();

        // NEW
        var tokenValidationParameters = jwtBearerOptions.TokenValidationParameters;

        // ...
    }
    // ...
}
// ...