如何使用 Microsoft 身份平台身份验证在 ASP.NET Core Web 应用程序中获取 JWT 令牌?

Posted

技术标签:

【中文标题】如何使用 Microsoft 身份平台身份验证在 ASP.NET Core Web 应用程序中获取 JWT 令牌?【英文标题】:How do I get hold of a JWT token in an ASP.NET Core Web App using Microsoft identity platform authentication? 【发布时间】:2021-12-24 04:30:55 【问题描述】:

我已经使用 Visual Studio 2022 和 .Net 6 创建了默认的 ASP.NET Core Web App 项目。

作为身份验证类型,我选择了微软识别平台。

如何获取 AzureAD 在 OpenID Connect 中为我生成的 JWT?

我已将program.cs中的身份验证服务更改为使用选项SaveTokens,如下所示:

using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    
        builder.Configuration.Bind("AzureAd", options);
        options.SaveTokens = true;
    );

builder.Services.AddAuthorization(options =>

    // By default, all incoming requests will be authorized according to the default policy.
    options.FallbackPolicy = options.DefaultPolicy;
);
builder.Services.AddRazorPages()
    .AddMicrosoftIdentityUI();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())

    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();


app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();
app.MapControllers();

app.Run();

我想要访问 JWT 令牌,以便将它们传递给我们拥有的定制服务。我不想重新生成它们,我想要 Microsoft 已签名的令牌。

为了测试获取它们,我尝试了 Microsoft.AspNetCore.Authentication 扩展中的 GetTokenAsync (在 Index.cshtml 中)

@page
@using Microsoft.AspNetCore.Authentication
@model IndexModel
@
    ViewData["Title"] = "Home page";


<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
    <p>Access Token: @await HttpContext.GetTokenAsync("OpenIdConnect","access_token")</p>
    <p>Refresh Token: @await HttpContext.GetTokenAsync("OpenIdConnect", "refresh_token")</p>
</div>

但是,可惜 - 我得到了空值。有任何想法吗?结果如下:

【问题讨论】:

不确定它是如何工作的,但令牌是否可能在 HttpOnly 浏览器 cookie 中? 你为什么要这个?单点登录? @CodeCaster - 这是一个好问题!我有一个自定义构建的后端服务,可以采用 JWT,确保它被正确信任(通过 OpenID 连接元数据内容中的证书检查它)并使用用户名。 @DavidG - 是的,但我认为这无关紧要,因为我的代码在服务器端运行。不过这很有趣,因为我在任何响应 cookie 中都看不到任何看起来特别像 JWT 的东西。 【参考方案1】:

好吧,我不知道为什么原始的 SaveTokens 方法不起作用,但这里有一种使它起作用的方法:

虽然不太一样,但可以满足我的需要。挂钩事件 OnTokenValidated,然后将其显式保存在标识上,如下所示(在 program.cs 中):

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(options =>
    
        builder.Configuration.Bind("AzureAd", options);
        options.Events.OnTokenValidated = context =>
        
            var accessToken = context.SecurityToken as JwtSecurityToken;
           

            if (accessToken != null)
            
                var identity = context.Principal.Identity as ClaimsIdentity;
                if (identity != null)
                
                    identity.AddClaim(new Claim("access_token", accessToken.RawData));
                
            

            return Task.FromResult(0);
        ;

    );

然后从 user.identity 访问它 - 仅用于测试(在 Index.cshtml 中):

<p>Access Token: @((User.Identity as ClaimsIdentity).Claims.Where( c => c.Type == "access_token").FirstOrDefault().Value)</p>

【讨论】:

以上是关于如何使用 Microsoft 身份平台身份验证在 ASP.NET Core Web 应用程序中获取 JWT 令牌?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用身份服务器 3 和 microsoft 团队应用程序使用 Azure AD 令牌进行身份验证

Microsoft 帐户 JWT 身份验证令牌如何签名?

Mac 使用Microsoft Remote Desktop无法连接至远程服务器,显示无法验证身份

Microsoft 身份平台 4-WebApp-your-API/4-1-MyOrg/

使用 Microsoft System.IdentityModel.Tokens.Jwt 在 Asp.net WebApi 中实现 JWT 身份验证

DotNet Core:如何跨平台客户端证书 TLS 身份验证?