.NET 8 DownstreamAPI 未进行身份验证

问题描述 投票:0回答:1

我已使用 Microsoft Identity 保护我的 .NET 8 Blazor 应用程序。在我的应用程序中,我想从我的 API 获取数据,并且也使用 Microsoft Identity 进行保护。我使用

DownstreamAPI
代表用户发送请求。我按照 Microsoft 的教程来设置我的应用程序。本教程基于 .NET 7,并且运行良好,因此我的设置似乎是正确的。

程序.cs

JwtSecurityTokenHandler.DefaultMapInboundClaims = false;

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi(
        new string[] {
            builder.Configuration.GetSection("DownstreamApi:Scopes:Read").Get<string>()!,
            builder.Configuration.GetSection("DownstreamApi:Scopes:Write").Get<string>()!
        }
    )
    .AddDownstreamApi("DownstreamApi", builder.Configuration.GetSection("DownstreamApi"))
    .AddInMemoryTokenCaches();

builder.Services.AddControllersWithViews()
        .AddMicrosoftIdentityUI();

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

// Add services to the container.
builder.Services.AddRazorPages();

应用程序设置.json

{
  "AzureAd": {
    "Authority": "https://login.microsoftonline.com/<DIRECTORY>/",
    "ClientId": "<CLIENT_ID>",
    "CallbackPath": "/signin-oidc",
    "SignedOutCallbackPath ": "/signout-oidc",
    "ClientCredentials": [
      {
        "SourceType": "ClientSecret",
        "ClientSecret": "<CLIENT_SECRET>"
      }
    ]
  },
  "DownstreamApi": {
    "Scopes": {
      "Read": "api://<CLIENT_ID>/ToDoList.Read",
      "Write": "api://<CLIENT_ID>/ToDoList.ReadWrite"
    },
    "BaseUrl": "https://localhost:7281"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

发送请求


@inject IDownstreamApi DownstreamApi;

...

@code
{
    ...
    private async Task GetFromApi()
    {
        try
        {
            Console.WriteLine("Getting token");
            var auth = await DownstreamApi.CallApiForUserAsync(
            ServiceName,
            options => options.RelativePath = "/api/authTest");
            Console.WriteLine(auth.StatusCode);
            Console.WriteLine(auth.Content.ReadAsStringAsync().Result);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

问题是它发送到 API 的不记名令牌似乎不正确。当我使用 jwt.io 销毁不记名令牌时,结果如下:

.NET 7(工作令牌):

.NET 8(无效令牌)

我似乎无法找出我错过了什么或做错了什么。

c# blazor microsoft-graph-api asp.net-core-webapi .net-8.0
1个回答
0
投票

就像您提到的那样,该令牌看起来是不正确的令牌。

我有下面的代码来生成 2 个代币,让我们看看差异。

var token = await TokenAcquisitionService.GetAccessTokenForUserAsync(new string[] { "User.Read" });
var token2 = await TokenAcquisitionService.GetAccessTokenForUserAsync(new string[] { "api://client_id/Tiny.Greet" });

我使用

ITokenAcquisition
服务生成我们调用外部 API 所需的访问令牌,该令牌也由 AAD 保护,第一个令牌用于调用 MS Graph API,第二个令牌用于我的自定义 API。

由于您没有分享任何代码来证明您拥有什么样的 Blazor 应用程序,所以我只能分享我所有的相关代码和设置。我使用的是 blazor web 应用程序 .net 8,它是从 blazor 服务器项目 .net 7 转换而来的。您可以查看 这个答案,看看我在迁移中更改了哪些内容。

using BlazorServer7To8.Data;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.UI;
using BlazorServer7To8;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.Configuration;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddDistributedTokenCaches();

builder.Services.AddControllersWithViews()
    .AddMicrosoftIdentityUI();

builder.Services.AddAuthorization(options =>
{
    // By default, all incoming requests will be authorized according to the default policy
    options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages();
//builder.Services.AddServerSideBlazor()
//    .AddMicrosoftIdentityConsentHandler();
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddMicrosoftIdentityConsentHandler();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddSingleton<WeatherForecastService>();

Index.razor
中,注入
ITokenAcquisition
服务来生成访问令牌,因为我们在Program.cs中已经有了
EnableTokenAcquisitionToCallDownstreamApi

@page "/"
@using Microsoft.Identity.Web
@inject Microsoft.Identity.Web.ITokenAcquisition TokenAcquisitionService

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

@code{
    protected override async Task OnInitializedAsync()
    {
        var token = await TokenAcquisitionService.GetAccessTokenForUserAsync(new string[] { "User.Read" });
        var token2 = await TokenAcquisitionService.GetAccessTokenForUserAsync(new string[] { "api://client_id/Tiny.Greet" });
        var a = 1;
    }
}

虽然我使用 Graph API 进行了下游 API 设置,但这并不影响我使用 On_behalf_flow 为其他范围生成另一个访问令牌。

"AzureAd": {
  "Instance": "https://login.microsoftonline.com/",
  "Domain": "tenant_Id",
  "TenantId": "tenant_Id",
  "ClientId": "client_Id",
  "CallbackPath": "/signin-oidc",
  "ClientSecret": "client_secret"
},
"DownstreamApi": {
  "BaseUrl": "https://graph.microsoft.com/v1.0",
  "Scopes": "User.ReadWrite.All"
}

我相信正确的访问令牌可以帮助解决您的错误。这是我对令牌生成的测试结果。

© www.soinside.com 2019 - 2024. All rights reserved.