【问题标题】:How do I get hold of a JWT token in an ASP.NET Core Web App using Microsoft identity platform authentication?如何使用 Microsoft 身份平台身份验证在 ASP.NET Core Web 应用程序中获取 JWT 令牌?
【发布时间】: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 的东西。

标签: c# asp.net-core jwt azure-ad-b2c


【解决方案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>

【讨论】:

    猜你喜欢
    • 2021-12-17
    • 2019-06-30
    • 2020-06-12
    • 2019-11-06
    • 2018-08-15
    • 2019-10-19
    • 2019-04-16
    • 2018-01-28
    • 1970-01-01
    相关资源
    最近更新 更多