使用WAM/MSAL的Azure令牌进行身份验证到自定义API

发布于 2025-02-12 09:17:09 字数 2053 浏览 0 评论 0原文

在编写桌面.NET核心应用程序的过程中,简要说明

使用MSAL对自定义API进行身份验证,我遇到了令牌的问题经理(WAM)。

背景

我正在使用一个桌面应用程序开发一个解决方案,该桌面应用调用自定义API,均为.NET Core 6编写。该应用最好能够使用当前用户帐户到API的情况下进行身份验证,而无需用户交互。 所有客户端都连接到特定的Azure租户,因此我的理解是,使用WAM检索机器的默认Microsoft帐户应完成此操作。

另一种解决方案是使用集成的Windows身份验证(IWA),但是我希望不使用此解决方案,因为它仅支持AD FS FS -FEDEDEDEDS用户 - 最适合应用程序也支持并非如此。

我可以使用MSAL.NET中的标准方法(以这种方式检索的标准方法来检索自定义API的必要令牌,

var scopes = new[] { "User.Read", $"api://{clientId}/access_as_user" };

var client = PublicClientApplicationBuilder.Create(clientId)
    .WithAuthority("https://login.microsoftonline.com/organizations/v2.0")
    .WithRedirectUri("customApp://auth")
    .Build();

var result = await client
    .AcquireTokenInteractive(scopes)
    .ExecuteAsync();

这种方式检索到了必要的令牌:

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

问题问题

是在我尝试使用WAM检索令牌时发生的问题:

var scopes = new[] { "User.Read", $"api://{clientId}/access_as_user" };

var client = PublicClientApplicationBuilder
    .Create(clientId)
    .WithBroker(true)
    .Build();

var result = await client
    .AcquireTokenInteractive(scopes)
    .WithAccount(PublicClientApplication.OperatingSystemAccount)
    .WithParentActivityOrWindow(NativeMethods.GetConsoleWindow())
    .ExecuteAsync();

返回令牌而没有错误,但是API不接受它,给出了错误 验证失败。

IDX10511:签名

  • -0000-C000-000000000000'而不是'api:// [my_client_id]'
  • 范围WAM令牌的( scp )包含默认的'Offline_access openID配置文件用户。

我尝试在WAM上明确设置权威并将URI重定向,但这似乎没有任何区别。

如果我从我的请求中删除图形 user.read 范围,则从WAM中获取令牌失败的错误,这表明这是必需的:

caa20002:AADST90008:用户或管理员尚未同意将应用程序与ID XX一起使用。发生这种情况是因为应用程序被错误配置:必须通过指定至少“登录和读取用户配置文件”权限来访问Microsoft Graph。

问题

  • 我正在通过WAM检索令牌的方式是否存在问题?
  • 我是否试图做不支持的事情? IE。我不能为此目的使用WAM吗?
  • API中身份验证的配置而不是将令牌的检索进行配置的问题?

任何帮助都将受到赞赏!

Brief description

In the process of writing a desktop .NET Core application that authenticates to a custom API using MSAL, I've encountered a problem with the tokens not containing the necessary scopes for the custom API - but only when retrieving the token using Web Account Manager (WAM).

Background

I'm developing a solution with a desktop app that calls a custom API, both written in .NET Core 6. The app should preferably be able to authenticate with the current user account to the API without requiring user interaction.
All the clients are connected to a specific Azure tenant, so my understanding is that using WAM to retrieve the default Microsoft account for the machine should accomplish this.

An alternative solution would be to use Integrated Windows authentication (IWA), but I would prefer to not use this solution as it only supports AD FS-federated users - it would be best for the application to also support cases where this is not so.

Previous steps

I am able to (interactively) retrieve the necessary token for the custom API using the standard method in MSAL.NET:

var scopes = new[] { "User.Read", 
quot;api://{clientId}/access_as_user" };

var client = PublicClientApplicationBuilder.Create(clientId)
    .WithAuthority("https://login.microsoftonline.com/organizations/v2.0")
    .WithRedirectUri("customApp://auth")
    .Build();

var result = await client
    .AcquireTokenInteractive(scopes)
    .ExecuteAsync();

The token retrieved in this way can be used to authenticate to the API which has been set up to use Microsoft.Identity:

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

Issue

The problem occurs when I attempt to instead use WAM for retrieving the token:

var scopes = new[] { "User.Read", 
quot;api://{clientId}/access_as_user" };

var client = PublicClientApplicationBuilder
    .Create(clientId)
    .WithBroker(true)
    .Build();

var result = await client
    .AcquireTokenInteractive(scopes)
    .WithAccount(PublicClientApplication.OperatingSystemAccount)
    .WithParentActivityOrWindow(NativeMethods.GetConsoleWindow())
    .ExecuteAsync();

The token is returned without error, but the API does not accept it, giving an error of IDX10511: Signature validation failed.

Attempting to debug the JWT tokens using jwt.ms I can observe several differences:

  • The audience (aud) of the WAM token is '00000003-0000-0000-c000-000000000000' rather than 'api://[my_client_id]'
  • The scopes (scp) of the WAM token includes the default 'offline_access openid profile User.Read' but not the one requested for the custom API 'access_as_user'.

I've tried explicitly setting the authority and redirect URI on the WAM but this does not seem to make any difference.

If I remove the graph User.Read scope from my request, getting the token from WAM fails with the following error which suggests it is required:

CAA20002: AADST90008: The user or administrator has not consented to use the application with ID xx. This happened because application is misconfigured: it must require access to Microsoft Graph by specifying at least "Sign in and read user profile" permission.

Questions

  • Is there an issue with the way I am retrieving the token through WAM?
  • Am I attempting to do something that isn't supported; ie. can I not use WAM for this purpose?
  • Is the issue with the configuration of the authentication in the API rather than with the retrieval of the token?

Any help is appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无法回应 2025-02-19 09:17:09

该问题与您传递的范围有关:

var scopes = new[] { "User.Read", $"api://{clientId}/access_as_user" };

2不同的API的范围:

  • user.read是MS Graph
  • API:// {clientId}/access_as_user

的范围,当您提出访问请求时, 是您的自定义资源,AAD应该仅查找第一个用户。阅读范围,然后将您返回MS Graph的访问权限,因此您在受众中看到的'00000003-0000-0000-0000-C000-00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000来价值。

尝试删除用户。从数组中阅读权限,看看它是否有效。

The issue is related with the scopes you are passing:

var scopes = new[] { "User.Read", 
quot;api://{clientId}/access_as_user" };

Which are scopes for 2 different APIs:

  • User.Read is a scope for MS Graph
  • api://{clientId}/access_as_user is your custom resource

When you make the request to get the accessToken, AAD should be looking only for the first User.Read scope, and returns you back an accessToken for MS Graph, hence the '00000003-0000-0000-c000-000000000000' value you see in your audience.

Try to remove the User.Read permission from the array and see if it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文