gpt4 book ai didi

c# - AzureAD 身份验证 : Audience validation failed. 受众不匹配

转载 作者:行者123 更新时间:2023-12-03 02:03:40 27 4
gpt4 key购买 nike

我在调用 API 中使用托管标识从 AzureAD 获取访问 token 。此用户分配的托管标识具有由分配给它的被调用 API 的应用程序注册 list 定义的应用程序角色。 token 在其内容中具有应用程序角色。到目前为止,一切都很好(我认为)。

当我将 token 附加到请求并调用预期的 API 时,我收到以下消息:

IDX10214: Audience validation failed. Audiences: '{clientId of called API App registration}'. Did not match: validationParameters.ValidAudience: 'api://{clientId of called API App registration}' or validationParameters.ValidAudiences: 'null'.

token 上的受众与内置 token 验证用作 ValidAudience 进行比较的受众之间的区别是前面的“api://”。 Azure Portal中定义的应用程序注册的应用程序URI确实是“api://{被调用的API应用程序注册的clientId}”

在生成 token 时,我尝试了许多不同的请求上下文变体...在 guid 中添加“api://”前缀,在应用程序 URI 中附加“/.default”,但无法让 token 被接受为有效。

这是我在被调用的应用程序上用于授权所提供的 token 的配置部分:

{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "the Guid matching the app registration Application ID",
"TenantId": "my tenant id",
"Audience": "api://{the Guid matching the app registration Application ID}"
}
}

这是我的 Program.cs:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Identity.Web;
using Microsoft.IdentityModel.Logging;

var builder = WebApplication.CreateBuilder(args);

IdentityModelEventSource.ShowPII = true;

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));

builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services
.AddApplicationInsightsTelemetry()
.AddHealthChecks()
.AddApplicationInsightsPublisher(saveDetailedReport: true);

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

app.UseHttpsRedirection();

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

app.MapControllers();
app.MapHealthChecks("/healthz");

app.Run();

这是我的 Controller :

using theModelNamespace.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Web.Resource;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace someMoreNamespace.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class NamesController : ControllerBase
{
[HttpGet("ping")]
//[AllowAnonymous]
public IActionResult PingOnly()
{
return Ok("Alive");
}

[HttpGet()]
//[Authorize(Roles = "Api.Read,Api.ReadWrite,Api.OtherUserApp")]
public async Task<IActionResult> GetNames()
{
AuthenticateResult authResult;
try
{
authResult = await HttpContext.AuthenticateAsync("Bearer");
}
catch (Exception ex)
{
var innerException = ex.InnerException != null ? ex.InnerException.Message : String.Empty;
var responseString = $"Error occurred in authentication: {ex.Message} {innerException}.";
return StatusCode(500, responseString);
}
try
{
HttpContext.ValidateAppRole("Api.OtherUserApp");
return Ok(Data.NameList);
}
catch (Exception ex)
{
var innerException = ex.InnerException != null ? ex.InnerException.Message : String.Empty;
var authResults = (authResult != null && authResult.Principal != null) ? $"succeeded: {authResult.Succeeded}, identityName: {authResult.Principal.Identity?.Name}, {authResult.Principal.Claims?.Select(x => $"{x.Type}: {x.Value}")}" : string.Empty;
authResults = authResults == String.Empty && authResult.Failure != null ? authResult.Failure.Message : authResults;
var claimContents = HttpContext != null && HttpContext.User != null ? String.Join(',', HttpContext.User.Claims.Select(x => $"{x.Type}: {x.Value}")) : String.Empty;
var responseString = $"Error occurred in validation: {ex.Message} {innerException}. \n\nClaim contents: {claimContents}\n\nAuthResults: {authResults}";
return StatusCode(500, responseString);
}
}

[HttpPost()]
//[Authorize(Roles = "Api.ReadWrite")]
public IActionResult PostName([FromBody] NamesModel nameModel)
{
Data.NameList.Add(nameModel);
return Ok(Data.NameList);
}

[HttpGet("Unreachable")]
//[Authorize(Roles = "Api.InvalidScope")]
public IActionResult UnreachableName([FromBody] NamesModel nameModel)
{
Data.NameList.Add(nameModel);
return Ok(Data.NameList);
}
}
}

我已注释掉授权属性,并添加了 HttpContext.AuthenticateAsync("Bearer") 以进行故障排除,因此我可以看到我在帖子开头列出的身份验证结果的输出。

我检查了 token ,“aud”声明确实是被调用 API 的应用程序注册的 clientId,并且没有前缀“api://” 我需要的角色似乎包含预期的 token 中的方式(角色:[“Api.OtherUserApp”)]。

匿名调用按预期工作正常。只有调用 AuthenticateAsync 的 get 端点有问题。

为了让被调用的 API 接受 token ,我缺少什么?

最佳答案

我尝试在我的环境中重现相同的内容。

我收到了同样的错误:

SecurityTokenInvalidAudienceException: IDX10214: Audience validation failed. Audiences: '50065xxxxx1e6fbd2ed06e'. Did not match: validationParameters.ValidAudience: 'api://xxxxxx1xx06e' or validationParameters.ValidAudiences: 'null'.

enter image description here

正如错误所示,受众与我们在 token 中获得的受众不匹配。确保记录了 Audience 中的值,并检查它是否等于 clientId。

Note that ,The valid audiences we can have is either clientId or AppId URI

此处我收到了值 applicationId 或 clientId 的受众错误,它与我请求的代码不匹配。

因为您提供了 AppId URI,即; api://,对于观众来说,是无效的。 So the correct one to be given here is ClientId .

ValidAudiences = new List<string> 
{
“CLIENTID”,
“APPID URI”
}

应用程序设置.json

{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "testtenant.onmicrosoft.com",
"ClientId": "xxxxxx",
"TenantId": "xxxxxxxxxxxx",
"ClientSecret": "xxxxx",
"Audience": "<clientId>",
"ClientCertificates": [
],
"CallbackPath": "/signin-oidc"
},
"DownstreamApi": {

"BaseUrl": "https://graph.microsoft.com/v1.0",
//"Scopes": "api://<clientId>/.default"
"Scopes": "https://graph.microsoft.com/.default"
},

enter image description here

<小时/>

这里可以在 api:///access_as_user 或 api://<clientId>/<scope value> 处公开 V2 端点应用程序的范围。 用于您的 webapi 。

  • 确保您的 accessTokenAcceptedVersion v2 端点颁发者为 2

enter image description here

对于 v1 范围是 <App ID URI>/.default

当我的发行人有 v1 端点时

enter image description here

在这种情况下,accessTokenAcceptedVersion 为 null or 1

<小时/>

我尝试在 Controller 中使用以下代码通过 API 获取用户显示名称。

HomeController:

[Authorize]
public async Task<IActionResult> Index()
{
var user = await _graphServiceClient.Me.Request().GetAsync();
ViewData["ApiResult"] = user.DisplayName;
ViewData["Givenname"] = user.GivenName;
return View();
}

我可以成功运行应用程序并调用我的 API enpoint,不会出现错误。

enter image description here

关于c# - AzureAD 身份验证 : Audience validation failed. 受众不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75365116/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com