ASP.NET Core JWT 不记名令牌自定义验证 [英] ASP.NET Core JWT Bearer Token Custom Validation

查看:29
本文介绍了ASP.NET Core JWT 不记名令牌自定义验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

经过大量阅读,我找到了一种实现自定义 JWT 不记名令牌验证器的方法,如下所示.

After a lot of reading, I have found a way to implement a custom JWT bearer token validator as below.

Starup.cs:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
         ILoggerFactory loggerFactory, IApplicationLifetime appLifetime)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();
        
    app.UseStaticFiles();
        
    app.UseIdentity();

    ConfigureAuth(app);
        
    app.UseMvcWithDefaultRoute();            
}

private void ConfigureAuth(IApplicationBuilder app)
{

    var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("TokenAuthentication:SecretKey").Value));


    var tokenValidationParameters = new TokenValidationParameters
    {
        // The signing key must match!
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = signingKey,
        // Validate the JWT Issuer (iss) claim
        ValidateIssuer = true,
        ValidIssuer = Configuration.GetSection("TokenAuthentication:Issuer").Value,
        // Validate the JWT Audience (aud) claim
        ValidateAudience = true,
        ValidAudience = Configuration.GetSection("TokenAuthentication:Audience").Value,
        // Validate the token expiry
        ValidateLifetime = true,
        // If you want to allow a certain amount of clock drift, set that here:
        ClockSkew = TimeSpan.Zero
    };

    var jwtBearerOptions = new JwtBearerOptions();
    jwtBearerOptions.AutomaticAuthenticate = true;
    jwtBearerOptions.AutomaticChallenge = true;
    jwtBearerOptions.TokenValidationParameters = tokenValidationParameters;
    jwtBearerOptions.SecurityTokenValidators.Clear();
    //below line adds the custom validator class
    jwtBearerOptions.SecurityTokenValidators.Add(new CustomJwtSecurityTokenHandler());
    app.UseJwtBearerAuthentication(jwtBearerOptions);
    
    var tokenProviderOptions = new TokenProviderOptions
    {
        Path = Configuration.GetSection("TokenAuthentication:TokenPath").Value,
        Audience = Configuration.GetSection("TokenAuthentication:Audience").Value,
        Issuer = Configuration.GetSection("TokenAuthentication:Issuer").Value,
        SigningCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256)
    };

    app.UseMiddleware<TokenProviderMiddleware>(Options.Create(tokenProviderOptions));
}

自定义验证器类:

public class CustomJwtSecurityTokenHandler : ISecurityTokenValidator
{
    private int _maxTokenSizeInBytes = TokenValidationParameters.DefaultMaximumTokenSizeInBytes;
    private JwtSecurityTokenHandler _tokenHandler;

    public CustomJwtSecurityTokenHandler()
    {
        _tokenHandler = new JwtSecurityTokenHandler();
    }
    
    public bool CanValidateToken
    {
        get
        {
            return true;
        }
    }

    public int MaximumTokenSizeInBytes
    {
        get
        {
            return _maxTokenSizeInBytes;
        }

        set
        {
            _maxTokenSizeInBytes = value;
        }
    }

    public bool CanReadToken(string securityToken)
    {
        return _tokenHandler.CanReadToken(securityToken);            
    }

    public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
    {
        //How to access HttpContext/IP address from here?

        var principal = _tokenHandler.ValidateToken(securityToken, validationParameters, out validatedToken);

        return principal;
    }
}

如果令牌被盗,我想添加一个额外的安全层来验证请求来自生成令牌的同一客户端.

In case of stolen token, I would like to add an additional layer of security to validate that the request is coming from the same client who generated the token.

问题:

  1. 有什么方法可以访问 CustomJwtSecurityTokenHandler 类中的 HttpContext 以便我可以添加基于当前客户端/请求者的自定义验证?
  2. 还有其他方法可以使用此类方法/中间件验证请求者的真实性吗?
  1. Is there any way I can access HttpContext within the CustomJwtSecurityTokenHandler class so that I could add custom validations based on the current client/requestor?
  2. Is there any other way we can validate the authenticity of the requestor using such method/middleware?

推荐答案

在 ASP.NET Core 中,可以使用 IHttpContextAccessor 服务获取 HttpContext.使用 DI 将 IHttpContextAccessor 实例传递给您的处理程序并获取 IHttpContextAccessor.HttpContext 属性的值.

In ASP.NET Core, HttpContext could be obtained using IHttpContextAccessor service. Use DI to pass IHttpContextAccessor instance into your handler and get value of IHttpContextAccessor.HttpContext property.

IHttpContextAccessor 服务默认未注册,因此您首先需要在您的 Startup.ConfigureServices 方法中添加以下内容:

IHttpContextAccessor service is not registered by default, so you first need to add the following in your Startup.ConfigureServices method:

services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

然后修改您的 CustomJwtSecurityTokenHandler 类:

private readonly IHttpContextAccessor _httpContextAccessor;

public CustomJwtSecurityTokenHandler(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
    _tokenHandler = new JwtSecurityTokenHandler();
}

... 

public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
{
    var httpContext = _httpContextAccessor.HttpContext;
}


您还应该将 DI 技术用于 JwtSecurityTokenHandler 实例化.如果您不熟悉依赖注入文档所有这些东西.


You should also use DI technique for JwtSecurityTokenHandler instantiation. Look into Dependency Injection documentation if you are new to all this stuff.

更新:如何手动解析依赖项(更多信息此处)

Update: how to manually resolve dependencies (more info here)

修改Configure方法使用IServiceProvider serviceProvider:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
         ILoggerFactory loggerFactory, IApplicationLifetime appLifetime,
         IServiceProvider serviceProvider)
{
    ...
    var httpContextAccessor = serviceProvider.GetService<IHttpContextAccessor>();
    // and extend ConfigureAuth
    ConfigureAuth(app, httpContextAccessor);
    ...
}

这篇关于ASP.NET Core JWT 不记名令牌自定义验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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