You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

同租户下WPF与Web服务AAD认证失败排查求助

问题描述

我有一个名为demoClient的WPF应用,已在Azure AD(AAD)中完成应用注册,注册名称为demoClientAppRegistration。点击demoClient的登录按钮时,需向名为demoServer的服务发送令牌进行认证。demoServer也已在AAD中完成注册,名称为demoServerAppRegistration,二者均属于同一租户tenantIDandNotDomainName。

WPF应用MainWindow.xaml.cs代码

public MainWindow()
{
    InitializeComponent();

    // Read the Azure AD app registration settings from app.config
    _clientId = "demoClientAppRegistrationClientId";
    
    _redirectUri = "http://localhost/demoClientWPFapp";
    _resource = "https://demoServer.azurewebsites.net";
    _authority = "https://login.microsoftonline.com/tenantIDandNotDomainName";
}

private async void LoginButton_Click(object sender, RoutedEventArgs e)
{
    string accessToken = await GetTokenAsync();
    string apiResponse = await CallApiAsync(accessToken);
    // handle the API response or display it in the UI
}

private async Task<string> GetTokenAsync()
{
    // Configure the PublicClientApplication
    IPublicClientApplication app = PublicClientApplicationBuilder
        .Create(_clientId)
        .WithRedirectUri(_redirectUri)
        .WithAuthority(_authority)
        .Build();

    // Define the authentication scopes
    string[] scopes = new string[] { $"{_resource}/Files.Read" };

    // Acquire an access token
    AuthenticationResult result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();

    return result.AccessToken;
}

private async Task<string> CallApiAsync(string accessToken)
{
    string apiUri = "api://demoClientAppRegistrationID/Files.Read";

    // Call the API with the access token
    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

    HttpResponseMessage response = await client.GetAsync(apiUri);

    return await response.Content.ReadAsStringAsync();
    // ...
}

demoServer .NET Core Web应用Program.cs代码(已发布至demoServer.azurewebsites.net)

class Program
{
private static readonly string clientId = "demoClientAppRegistrationId";
private static readonly string authority = "https://login.microsoftonline.com/tenantIDandNotDomainName";
private static readonly string apiUri = "api://demoServerAppRegistrationId";

    static async Task Main(string[] args)
    {
        var app = PublicClientApplicationBuilder.Create(clientId)
            .WithAuthority(authority)
            .Build();

        string[] scopes = new[] { apiUri + "/Files.Read" };
        var result = await app.AcquireTokenInteractive(scopes).ExecuteAsync();

        Console.WriteLine($"Access token: {result.AccessToken}");

        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

        HttpResponseMessage response = await client.GetAsync(apiUri);
        string content = await response.Content.ReadAsStringAsync();

        Debug.WriteLine($"Response: {content}");
    }
}

遇到的错误

我已正确配置权限,但仍收到错误:

AADSTS500011: 租户tenantIDandNotDomainName中未找到名为https://demoServer.azurewebsites.net的资源主体。可能是应用未被租户管理员安装或未获得用户同意,也可能是认证请求发送至错误租户。

更新记录

  1. 按照@Sridevi的方法操作后,出现新错误:invalid_client: AADSTS7000215: 提供的客户端密钥无效。确保为应用程序'xxx'提供的密钥正确,并且没有过期。
  2. 我认为当前流程不符合需求,已尝试新流程,现遇到另一个错误:JWT Bearer令牌受众无效,尽管令牌中包含正确的受众

问题分析与解决方案

初始错误AADSTS500011的原因及修复

核心问题

你在WPF应用中请求令牌时,使用的_resource是服务的部署地址https://demoServer.azurewebsites.net,但AAD查找资源主体是根据应用注册的标识符URI,而非服务的外部访问地址。demoServerAppRegistration的标识符URI才是AAD识别该服务的唯一标识。

修复步骤

  1. 登录Azure门户,找到demoServerAppRegistration的应用注册页面,复制其标识符URI(格式通常为api://{demoServerAppRegistrationId})
  2. 修改WPF应用中的_resource值为该标识符URI:
    _resource = "api://demoServerAppRegistrationId"; // 替换为实际的标识符URI
    
  3. 同步修改GetTokenAsync中的请求范围:
    string[] scopes = new string[] { $"{_resource}/Files.Read" };
    

第二个错误AADSTS7000215的原因及修复

这个错误直接指向客户端密钥无效,常见原因及解决办法:

  • 密钥过期或已删除:进入demoClientAppRegistration的“证书和密码”选项卡,检查现有密钥状态,过期则删除并创建新密钥
  • 密钥值输入错误:确认代码中使用的是密钥创建时显示的完整字符串(注意创建时仅显示一次,需妥善保存,不是密钥ID)
  • 未配置客户端密钥:若应用注册中没有密钥,直接创建新的客户端密钥并更新代码配置

第三个错误:JWT受众无效的原因及修复

即使令牌包含正确受众仍报错,通常是以下问题导致:

1. API服务端受众配置错误

在demoServer的认证中间件中,必须配置自身的标识符URI作为受众,而非客户端的。示例配置(ASP.NET Core):

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.Authority = "https://login.microsoftonline.com/tenantIDandNotDomainName";
        options.Audience = "api://demoServerAppRegistrationId"; // 这里是demoServer的标识符URI
    });

2. 令牌请求范围与API定义不匹配

确保WPF应用请求的Files.Read范围,是demoServerAppRegistration在“公开API”选项卡中已定义的自定义权限范围,且已授权给demoClientAppRegistration

3. 令牌aud声明与服务端配置不一致

用jwt.ms解析令牌,检查aud字段的值,确保和服务端配置的Audience完全一致(注意大小写、是否有多余斜杠等细节)


内容的提问来源于stack exchange,提问作者MChak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 13:08:12