如何使 AzureAD 和自定义 JWT 令牌在 Web API 中并行工作?

Posted

技术标签:

【中文标题】如何使 AzureAD 和自定义 JWT 令牌在 Web API 中并行工作?【英文标题】:How to make AzureAD and custom JWT tokens to work side by side in web API? 【发布时间】:2019-06-24 23:05:38 【问题描述】:

API 客户端使用 API 本身(标准)或 Azure AD 颁发的 JWT 令牌。

当我只启用自定义(标准)不记名身份验证时,一切正常,没有任何问题。

此外,当我仅启用 Azure AD 不记名身份验证时,一切正常。

当我同时启用它们时,其中一个停止工作。

这是我的 .Net 核心 API 设置:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(BuildStandardJwtBearerOptions);
services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
    .AddAzureADBearer(options => Configuration.Bind("AzureAd", options));

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)

private void BuildStandardJwtBearerOptions(JwtBearerOptions options)

    var settings = GetStandardTokenSettings(null);

    options.IncludeErrorDetails = true;
    options.RequireHttpsMetadata = false;
    options.SaveToken = true;

    var signingKeyBytes = Encoding.UTF8.GetBytes(settings.SecretKey);
    var signingKey = new SymmetricSecurityKey(signingKeyBytes);
    options.TokenValidationParameters = new TokenValidationParameters
    
        ValidIssuer = settings.Issuer,
        ValidAudience = settings.Issuer,
        IssuerSigningKey = signingKey
    ;

以下是客户端发送 Azure AD 令牌时的错误示例:

Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:信息: 验证令牌失败。

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException: IDX10500:签名验证失败。未提供安全密钥 验证签名。在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(字符串 令牌,令牌验证参数验证参数)在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(字符串 令牌、TokenValidationParameters 验证参数、SecurityToken& 验证令牌)在 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync() Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:信息: AzureADJwtBearer 未通过身份验证。失败消息:IDX10500: 签名验证失败。没有提供安全密钥给 验证签名。 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:信息: 与 action = "List", controller = "Account" 匹配的路由。 执行动作 BookRental.Api.Controllers.AccountController.List (BookRental.Api) Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:信息: 授权失败。 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:信息: 过滤器请求授权失败 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'。 Microsoft.AspNetCore.Mvc.ChallengeResult:信息:正在执行 ChallengeResult 与身份验证方案 ()。 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler:信息: AuthenticationScheme:AzureADJwtBearer 受到质疑。 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:信息: 执行的动作 BookRental.Api.Controllers.AccountController.List (BookRental.Api) 在 7.1108 毫秒内 Microsoft.AspNetCore.Hosting.Internal.WebHost:信息:请求 在 16.8394 毫秒 401 内完成

我怎样才能让这两种类型的令牌并排工作?

【问题讨论】:

【参考方案1】:

您可以尝试通过指示两种身份验证方案来更改授权系统的默认策略:

services.AddAuthentication(AzureADDefaults.BearerAuthenticationScheme)
    .AddAzureADBearer(options => Configuration.Bind("AzureAd", options))
    .AddJwtBearer("scc", BuildStandardJwtBearerOptions); 

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

services
    .AddAuthorization(options =>
    
        options.DefaultPolicy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .AddAuthenticationSchemes(AzureADDefaults.BearerAuthenticationScheme, "scc")
            .Build();
    );

【讨论】:

以上是关于如何使 AzureAD 和自定义 JWT 令牌在 Web API 中并行工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 python 中验证来自 AzureAD 的 JWT?

.NET Core 3.0 中 AspNetUserToken 和自定义 JWT 令牌之间的区别

在 c# 中为使用 AzureAd 登录的当前用户获取 Jwt 令牌

如何在登录时在 JWT 令牌中从 Azure Active Directory 传递自定义扩展属性?

MSAL Angular:如何从 JWT 令牌中检索用户角色?

如何在不使用会话的情况下获取图形令牌?