首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MsalClientException IDW10104来自GetAccessTokenForAppAsync

MsalClientException IDW10104来自GetAccessTokenForAppAsync
EN

Stack Overflow用户
提问于 2022-03-24 09:57:00
回答 1查看 281关注 0票数 0

我在Azure中将ASP.NET核心Web设置为App,并在AzureAd中注册了一个应用程序

在appsettings.json中,我已经(非殖化)

代码语言:javascript
复制
 "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "ourdomain.co.uk",
    "TenantId": "n9n999n9-9999-nnnn-9n9n9-9n9n9n9n9n9",
    "ClientId": "81933a15-157f-45b0-bc32-3d7d6d62f4a7",
    "Audience": "https://ourdomain.co.uk/breathe.notifications-service",
    "ClientSecret": "a6a6a6a~EEizqWNa8itAAAjcrycxnCtxaVgKTFx"
  },

该应用程序在Azure中拥有API权限,允许我调用另一个应用程序服务,即审计。审计服务没有定义任何特定的作用域,但它有一个名为Audit.Write的应用程序角色。

在调用API中,我需要获得一个令牌来调用审计,所以我运行以下代码

代码语言:javascript
复制
var accessToken = await this.tokenAcquisition.GetAccessTokenForAppAsync(this.auditApiScope);
this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

注意对GetAccessTokenForAppAsync的调用,而不是更常见的GetAccessTokenForUserAsync

我要传递的作用域字符串是

代码语言:javascript
复制
https://ourdomain.co.uk/us.audit-service/.default

当我调用GetAccessTokenForAppAsync时,MSALException失败了

IDW10104:客户端机密证书和客户端证书都不能为空或空白,在调用web时,只能在web应用程序的配置中包含一个。例如,在appsettings.json文件中。

客户端秘密在AzureAd配置中,我没有指定证书。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-24 13:12:04

我现在有了这方面的工作,有两个选择,但在我概述这些之前,我需要提供一些额外的背景。

这个Web和我们创建的其他网站为Azure Ad用户和Azure B2C用户提供了功能。这个功能最初是在Microsoft.Identity.Web 1.11.0中实现的,我们hjave在发布后一直使用1.11.0。然而,我们总是有一个问题,就是我们会产生数以千计的异常,因为MSAL混淆了要使用哪种方案。

我们看到了这个博客文章,在IDX10501核心3.1中使用多个身份验证方案时删除误导性的ASP.NET日志,在这个github线程,https://github.com/oliviervaillancourt/blog/issues/3中有更多的细节。

我们的Startup.cs配置服务如下所示

代码语言:javascript
复制
public void ConfigureServices(IServiceCollection services)
{
    services.AddMicrosoftIdentityWebApiAuthentication(this.configuration)
                                                            .EnableTokenAcquisitionToCallDownstreamApi()
                                                            .AddInMemoryTokenCaches();

    services.AddAuthentication()
            .AddMicrosoftIdentityWebApi(this.configuration, "AzureAdB2C", "B2CScheme", true);

    services.AddAuthentication("AzureAD_OR_AzureAdB2C")
                .AddMicrosoftIdentityWebApi(
                                            jwtBearerOptions =>
                                            {
                                                var azureAdB2CConfig = this.configuration.GetSection("AzureAdB2C");
                                                jwtBearerOptions.ForwardDefaultSelector = context =>
                                                {
                                                    var token = string.Empty;

                                                    if (context.Request.Headers.TryGetValue("Authorization", out var value))
                                                    {
                                                        string authorization = value;
                                                        if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
                                                        {
                                                            token = authorization.Substring("Bearer ".Length).Trim();
                                                        }
                                                    }

                                                    if (token == null)
                                                    {
                                                        this.logger.LogInformation($"Cannot get the Token out of the Authorization header");
                                                    }

                                                    var jwtHandler = new JwtSecurityTokenHandler();

                                                    if (jwtHandler.CanReadToken(token))
                                                    {
                                                        var jwtToken = jwtHandler.ReadJwtToken(token);
                                                        var expectedB2CIssuer = $"{azureAdB2CConfig.GetValue<string>("Instance")}/{azureAdB2CConfig.GetValue<string>("TenantId")}/v2.0/";

                                                        if (string.Compare(jwtToken.Issuer, expectedB2CIssuer, true) == 0)
                                                        {
                                                            // Claim is from B2C so this request should be validated against the B2C scheme.
                                                            this.logger.LogInformation($"Request is with a B2C issued token so refer to B2CScheme. Token issuer: {jwtToken.Issuer} B2C Issuer: {expectedB2CIssuer}");
                                                            return "B2CScheme";
                                                        }
                                                        else
                                                        {
                                                            this.logger.LogInformation($"Request is not with a B2C issued token so refer to Bearer scheme. Token issuer: {jwtToken.Issuer} B2C Issuer: {expectedB2CIssuer}");
                                                        }
                                                    }
                                                    else
                                                    {
                                                        this.logger.LogInformation("Request token could not be read so refer to Bearer scheme");
                                                    }

                                                    return "Bearer";
                                                };
                                            },
                                            identityOptions =>
                                            {
                                                var azureAdB2CConfig = this.configuration.GetSection("AzureAdB2C");
                                                identityOptions.Instance = azureAdB2CConfig.GetValue<string>("Instance");
                                                identityOptions.TenantId = "AzureAD_OR_AzureAdB2C";
                                                identityOptions.ClientId = "AzureAD_OR_AzureAdB2C";
                                            },
                                            "AzureAD_OR_AzureAdB2C",
                                            false);

    services.AddControllers()
            .AddNewtonsoftJson();

    services.AddLogging(options =>
    {
        // hook the Console Log Provider
        options.AddConsole();
        options.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);

        // hook the Application Insights Provider
        options.AddFilter<ApplicationInsightsLoggerProvider>(string.Empty, Microsoft.Extensions.Logging.LogLevel.Trace);

        // pass the InstrumentationKey provided under the appsettings
        options.AddApplicationInsights(this.configuration["APPINSIGHTS_INSTRUMENTATIONKEY"]);
    });
  
}

ForwardDefaultSelector使用的逻辑帮助我们处理多个方案,并将ASP.NET转发到正确的方案。

现在回到答案。

但是,如果我删除了ForwardDefaultSelector,我就不再获得IDW10104,这就是我们用来重构所有无关的异常方案的方法,因此这实际上是行不通的。

唯一可行的选择是将Web从最新版本的Microsoft.Identity.Web 1.21.1移到1.16.0。导致我们得到异常的问题是在1.16.1中提出的。我将在1.16.1中就MSAL github提出一个问题。我们以前使用的是1.11.0。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71600292

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档