新文章 网摘 文章 随笔 日记

.NET Core 中的自定义身份验证(验证 JWT 令牌 , 值得阅读)

 

介绍

你好,朋友们!!!!在本文中,我将介绍如何实现自定义身份验证处理程序以及如何将其作为中间件注入 .NET Core 中。使用自定义身份验证处理程序,我们将验证请求(授权标头)中的 JWT(JSON Web 令牌)令牌。

智威汤逊令牌验证

  1. 创建自定义身份验证处理程序以验证 JWT 令牌
  2. 从自定义授权服务器 (OAuth) 获取元数据
  3. 在中间件中注入身份验证处理程序

自定义身份验证的工作原理

创建自定义身份验证处理程序

第 1 步

创建 .NET 核心项目。

第 2 步

创建“身份验证管理器”类。它用于从授权服务器获取元数据。

第 3 步

使用 NuGet 包管理器将以下引用添加到项目中。

  • Microsoft.IdentityModel.Protocols
  • Microsoft.IdentityModel.Protocols.OpenIdConnect

步骤4

“身份验证管理器”类中添加以下代码。在这里,我们从授权服务器获取元数据。因为,不是将签名密钥保留在本地配置中,而是使用元数据终结点从授权服务器获取。以下终结点返回与组织授权服务器相关的 OpenID 连接或 OAuth 2.0 元数据。

奥奥特 - https://${yourAuthServer}/.well-known/oauth-authorization-server

public static class AuthConfigManager {
    private static IConfigurationManager < OpenIdConnectConfiguration > configManager;
    private static IConfigurationManager < OpenIdConnectConfiguration > GetConfigurationManager(string metadataAddress) {
        if (configManager == null) {
            return new ConfigurationManager < OpenIdConnectConfiguration > (metadataAddress, new OpenIdConnectConfigurationRetriever(), new HttpDocumentRetriever());
        }
        return configManager;
    }
    public static OpenIdConnectConfiguration GetMetaData(string metadataAddress) {
        var configManager = GetConfigurationManager(metadataAddress);
        var metaData = configManager.GetConfigurationAsync(
            default).Result;
        return metaData;
    }
}
C#

步骤5

创建“自定义自动处理程序”类。它用于根据“令牌验证参数”验证 JWT 令牌。

步骤 6

在“自定义自动处理程序”类中添加以下代码,以从“身份验证管理器”中获取元数据。

public bool IsValidToken(string jwtToken, string issuer, string audience, string metadataAddress) {
    var openIdConnectConfig = AuthConfigManager.GetMetaData(metadataAddress);
    var signingKeys = openIdConnectConfig.SigningKeys;
    return ValidateToken(jwtToken, issuer, audience, signingKeys);
}
C#

第 7 步

在“自定义自动处理程序”中添加以下代码以验证 JWT 令牌。如果发生任何异常,则引发该异常。

private bool ValidateToken(string jwtToken, string issuer, string audience, ICollection < SecurityKey > signingKeys) {
    try {
        var validationParameters = new TokenValidationParameters {
            RequireExpirationTime = true,
                ValidateLifetime = true,
                ClockSkew = TimeSpan.FromMinutes(1),
                RequireSignedTokens = true,
                ValidateIssuerSigningKey = true,
                IssuerSigningKeys = signingKeys,
                ValidateIssuer = true,
                ValidIssuer = issuer,
                ValidateAudience = true,
                ValidAudience = audience
        };
        ISecurityTokenValidator tokenValidator = new JwtSecurityTokenHandler();
        var claim = tokenValidator.ValidateToken(jwtToken, validationParameters, out
            var _);
        var scope = claim.FindFirst(c => c.Type.ToLower() == "<Here Scope Type>" && (c.Value.ToLower() == "<Here Scope>"));
        if (scope == null) throw new Exception("404 - Authorization failed - Invalid Scope");
        return true;
    } catch (Exception ex) {
        throw new Exception("404 - Authorization failed", ex);
    }
}
C#

在上面的方法中,验证 JWT 令牌中的以下参数,

  • 需要过期时间 = 指示令牌是否必须具有“过期”值。
  • 验证生命周期 = 检查令牌是否已过期
  • 时钟扭曲 = 验证时间时要应用的时钟偏差
  • 要求签名令牌 = 它指示安全令牌在未签名时是否可以被视为有效。
  • 验证颁发者签名密钥 = 验证令牌的签名
  • 颁发者签名密钥 = 验证令牌的签名
  • 验证颁发者 = 验证生成令牌的服务器
  • 有效颁发者 = 颁发者值将用于对照令牌的颁发者进行检查
  • 验证身份 = 验证令牌的接收者
  • 有效受众 = 将使用受众价值来检查令牌的受众

第 8 步

发行者的值,受众存储在应用程序设置.json文件中,如下所示,

{
  "JwtToken": {
    "Issuer": "TestIssuer.com",
    "Audience": "Test"
  }
}
C#

第 9 步

创建“身份验证中间软件”类并添加以下代码以调用 JWT 验证。在下面的代码中,只需从请求中的授权标头中提取 JWT 令牌,然后调用“IsValidToken()”函数来验证 JWT 令牌。如果发生任何异常,则向用户发送“未经授权”消息和“401”状态代码。

public class AuthMiddleware {
    private readonly RequestDelegate next;
    private readonly IConfiguration configuration;
    public AuthMiddleware(IConfiguration appConfigurationr) {
        configuration = appConfigurationr;
    }
    public async Task Invoke(HttpContext httpContext) {
        try {
            var path = httpContext.Request.Path;
            string token = string.Empty;
            string issuer = configuration["JwtToken:Issuer"]; //Get issuer value from your configuration
            string audience = configuration["JwtToken:Audience"]; //Get audience value from your configuration
            string metaDataAddress = issuer + "/.well-known/oauth-authorization-server";
            CustomAuthHandler authHandler = new CustomAuthHandler();
            var header = httpContext.Request.Headers["Authorization"];
            if (header.Count == 0) throw new Exception("Authorization header is empty");
            string[] tokenValue = Convert.ToString(header).Trim().Split(" ");
            if (tokenValue.Length > 1) token = tokenValue[1];
            else throw new Exception("Authorization token is empty");
            if (authHandler.IsValidToken(token, issuer, audience, metaDataAddress)) await next(httpContext);
        } catch (Exception) {
            httpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
            HttpResponseWritingExtensions.WriteAsync(httpContext.Response, "{\"message\": \"Unauthorized\"}").Wait();
        }
    }
}
C#

第 10 步

在“启动”类的“配置”方法中配置“身份验证中间软件

每当调用 API 时,请求都会传递到“身份验证中间软件”,它将在转到相应的控制器之前验证 JWT 令牌(请求中的授权标头)。

构建自定义身份验证的用途是,我们可以根据用例验证 JWT 令牌,还可以自定义验证部分。

希望你喜欢它。如果您对此有任何疑问或意见,请在评论中告诉我。

.NET Core 中的自定义身份验证(验证 JWT 令牌) (c-sharpcorner.com)

 

posted @ 2022-10-24 19:37  岭南春  阅读(953)  评论(0)    收藏  举报