我在Azure中将ASP.NET核心Web设置为App,并在AzureAd中注册了一个应用程序
在appsettings.json中,我已经(非殖化)
"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中,我需要获得一个令牌来调用审计,所以我运行以下代码
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
我要传递的作用域字符串是
https://ourdomain.co.uk/us.audit-service/.default当我调用GetAccessTokenForAppAsync时,MSALException失败了
IDW10104:客户端机密证书和客户端证书都不能为空或空白,在调用web时,只能在web应用程序的配置中包含一个。例如,在appsettings.json文件中。
客户端秘密在AzureAd配置中,我没有指定证书。
发布于 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配置服务如下所示
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。
https://stackoverflow.com/questions/71600292
复制相似问题