从 .NET 控制台应用登录到 Azure 管理 API

Login to Azure Management API from .NET Console app

我正在创建一个登录到我的业务线应用程序并调用一些 Azure 管理 API 的控制台应用程序。我的客户端应用程序有权执行这两项操作,它可以从我的 Blazor WASM Web 应用程序从客户端执行此操作,这是 Azure 中的权限: 我有这个控制台应用程序的身份验证代码(用于登录我的 Web 应用程序)

public static async Task<AuthenticationResult> GetTokenAsync(string userName)
        {
            //ref https://github.com/AzureAD/microsoft-authentication-extensions-for-dotnet/blob/master/sample/ManualTestApp/Program.cs
            IPublicClientApplication app = PublicClientApplicationBuilder
            .Create(AuthCacheConfig.ClientId)
            .WithAuthority(AuthCacheConfig.Authority)
            .WithRedirectUri(AuthCacheConfig.RedirectURI)
            .Build();
            MsalCacheHelper cacheHelper = await CreateCacheHelperAsync().ConfigureAwait(false);
            cacheHelper.RegisterCache(app.UserTokenCache);
            IEnumerable<IAccount> accounts = await app.GetAccountsAsync();
            AuthenticationResult result;
            if (accounts.Any())
            {
                IAccount selectedAccount = GetSelectedAccount(accounts.ToList(), userName);
                try
                {
                    result = await app.AcquireTokenSilent(AuthCacheConfig.Scopes, selectedAccount)
                                .ExecuteAsync();
                }
                catch (MsalUiRequiredException)
                {
                    result = await app.AcquireTokenInteractive(AuthCacheConfig.Scopes)
                                .ExecuteAsync();
                }
            }
            else
            {
                result = await app.AcquireTokenInteractive(AuthCacheConfig.Scopes)
                                .ExecuteAsync();
            }
            return result;
        }

其中 AuthCacheConfig.ClientId = MYAPPCLIENTID AuthCacheConfig.Authority = "https://login.microsoftonline.com/common"AuthCacheConfig.Scopes 是我尝试获取应用程序令牌时的应用程序范围,而 https://management.azure.com/user_impersonation 是我尝试获取 ARM 令牌时的应用程序范围。 我查看了 Web 应用程序可以在 JWT.ms 中成功生成的令牌并得到以下结果:

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "",
  "kid": ""
}.{
  "aud": "https://management.azure.com",
  "iss": "https://sts.windows.net/TENANTID/",
  "iat": 1605579273,
  "nbf": 1605579273,
  "exp": 1605583173,
  "acr": "1",
  "aio": "REMOVED FOR PRIVACY",
  "amr": [
    "rsa",
    "mfa"
  ],
  "appid": "MYCLIENTAPPID",
  "appidacr": "0",
  "family_name": "MYLASTNAME",
  "given_name": "MYFIRSTNAME",
  "groups": [
    "AADGROUP0",
    "AADGROUP1"
  ],
  "ipaddr": "MYIPADDRES",
  "name": "MYNAME",
  "oid": "MYOID",
  "puid": "REMOVED FOR PRIVACY",
  "rh": "REMOVED FOR PRIVACY",
  "scp": "user_impersonation",
  "sub": "REMOVED FOR PRIVACY",
  "tid": "MYTENANTID",
  "unique_name": "MYUPN",
  "upn": "MYUPN",
  "uti": "REMOVED FOR PRIVACY",
  "ver": "1.0",
  "wids": [
    "wid0",
    "wid1",
    "wid2"
  ],

这是我从控制台应用调用时的令牌:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "REMOVED FOR PRIVACY"
}.{
  "aud": "MYAPPID",
  "iss": "https://login.microsoftonline.com/TENANTID/v2.0",
  "iat": 1605579071,
  "nbf": 1605579071,
  "exp": 1605582971,
  "aio": "REMOVED FOR PRIVACY",
  "name": "MYNAME",
  "oid": "MYOID",
  "preferred_username": "mMYUPN",
  "rh": "REMOVED FOR PRIVACY",
  "roles": [
    "Administrator"
  ],
  "sub": "REMOVED FOR PRIVACY",
  "tid": "MYTENANTID",
  "uti": "REMOVED FOR PRIVACY",
  "ver": "2.0"
}

我找不到在 MSAL 库中指定受众的方法,有没有办法做到这一点?从我在令牌中看到的内容来看,Microsoft STS 没有看到该请求是针对 Azure 服务管理范围的?

错误是因为 V1 端点期望观众声明中有斜线,而另一个端点将 API 名称与范围分开。

TL;DR 将作用域从 var scopes = new[] {"https://management.core.windows.net/user_impersonation"}; 更改为 var scopes = new[] {"https://management.core.windows.net//user_impersonation"};,它将起作用。

为了节省其他人两个小时的谷歌搜索,这里是关于仍然不支持 v2 令牌的调用端点的文档:https://docs.microsoft.com/en-us/azure/active-directory/develop/msal-v1-app-scopes