0

我们有一个使用 MSAL 并使用 Azure AD 生成令牌的应用程序。我们需要该应用程序调用另一个 API,并且我们正在传递当前令牌。这一切都很好。我们有两个不同的应用程序,我将包含一些代码来展示受众(其他客户端 ID)如何能够进行身份验证

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(opt =>
                {
                    opt.Audience = Configuration["AzureAd:ResourceId"];
                    opt.Authority = $"{Configuration["AzureAd:Instance"]}/{Configuration["AzureAd:TenantId"]}";
                    opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                    {
                        ValidAudiences = new string[] { "e8zzz-3304-43e0-aaaa-zzzzzzzzz" }
                    };
                });

所以认证不是问题。我们正在使用 GraphServiceClient 来访问图形 api,但是我们从 Authorization 标头获得的令牌是从另一个应用程序传递的令牌,并且具有与另一个应用程序相关联的客户端 ID。一切运行良好,直到到达 AcquireTokenAsync 行,并且返回的问题状态为“断言受众与呈现断言的客户端应用程序不匹配。断言中的受众是“{其他应用程序 ID}”,而预期的受众是“ {app id of the api}”或此应用程序的应用程序 Uris 之一,应用程序 ID 为“{app id of the api}”(API APP)。下游客户端必须为预期的受众(制作的应用程序)请求令牌OBO 请求)并且此应用程序应使用该令牌作为断言。”

public async Task<GraphServiceClient> GetAuthenticatedClient()
        {
            var httpContext = this.httpContextAccessor.HttpContext;
            if (httpContext != null)
            {
                StringValues authorizationToken;
                httpContext.Request.Headers.TryGetValue("Authorization", out authorizationToken);

                var authHeader = authorizationToken.FirstOrDefault();
                if (authHeader != null && authHeader.StartsWith("bearer", StringComparison.OrdinalIgnoreCase))
                {
                    var token = authHeader.Substring("Bearer ".Length).Trim();

                    var clientCredential = new ClientCredential(_authOptions.ClientId, _authOptions.ClientSecret);
                    var authenticationContext = new AuthenticationContext($"https://login.microsoftonline.com/{_authOptions.TenantId}");
                    var authenticationResult = await authenticationContext.AcquireTokenAsync("https://graph.microsoft.com", clientCredential, new UserAssertion(token));

                    var delegateAuthProvider = new DelegateAuthenticationProvider((requestMessage) =>
                    {
                        requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", authenticationResult.AccessToken);

                        return Task.FromResult(0);
                    });

                    return new GraphServiceClient(delegateAuthProvider);
                }
            }

            throw new UnauthorizedAccessException("Invalid User token.");
        }

另一点是我对 Azure AD 的访问权限仅限于只读。另一组控制着它。这有点政治性,所以我无法更新内容以自行尝试,任何更改至少需要一天的时间。

我还在 api 的清单中设置了 knownApplications。

我可能“可以”让它使用来自其他应用程序的客户端凭据只是为了查看它的工作,但这不是一个很好的答案,因为我们不想知道其他应用程序的那些凭据。当然,这正在完成并且我错过了一些明显的东西。提前非常感谢..我希望,如果有的话,这对其他人有用。

4

1 回答 1

0

您能否尝试将令牌从 App 传递到Postman中的 API,并查看是否获取正确的 App ID。

您还可以尝试使用 Azure AD 和 OpenID Connect 在 Web 应用程序中调用 Web API 的示例。

于 2022-02-24T07:30:30.867 回答