简体   繁体   中英

How do I get hold of a JWT token in an ASP.NET Core Web App using Microsoft identity platform authentication?

I have created the default ASP.NET Core Web App project using Visual Studio 2022 and .Net 6.

As the authentication type I have chosen Microsoft identify platform.

示例应用设置

How do I get hold of the JWT that AzureAD generates for me as part of OpenID Connect?

I have changed the authentication service in the program.cs to use the option SaveTokens as follows:

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();

I want access to the JWT tokens so I can pass them to a bespoke service we have. I do not want regenerate them, I want the tokens that Microsoft have signed.

To test getting hold of them I have tried GetTokenAsync from the Microsoft.AspNetCore.Authentication extensions like so (in 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>

But alas - I get nulls back. Any ideas? Result below:

没有 JWT 信息的网页示例

Well I'm none the wiser why the original SaveTokens method doesn't work but here is a way to make it work:

It's not quite to same but gets me what I need. Hook into the event OnTokenValidated and then save it explicitly on the identity as follows (in 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);
        };

    });

And then access it from the user.identity - following just for testing (in Index.cshtml):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM