我实现了此处描述的内容:使用电子邮件邀请注册
当Azure应用程序服务使用B2C Azure AD进行身份验证\登录时,这可以完美地工作,也就是说,当我通过B2C AD验证的帐户登录时,会发送邀请电子邮件。
现在我有另一个应用程序服务指向 B2B Azure AD 进行用户登录验证,因此当我通过 B2B AD 验证的帐户登录时会发送邀请电子邮件。
包含指向 B2C AD 的邀请链接的电子邮件已正确发送。但是,单击链接后,B2C 注册邀请策略将采取行动,并且我会看到 401 错误(未经授权)。这看起来 B2C 策略出于任何原因都无法访问策略配置中设置的元数据端点...
显示的消息是:
相关 ID:78292d04-7184-42d0-ac2d-a60bb98a532f
时间戳:2019-09-20 16:19:25Z AADB2C:元数据端点
'https://mywebsite.azurewebsites.net/.well-known/openid-configuration'
返回以下状态代码:“401”
这是自定义注册邀请策略
<ClaimsProvider>
,其中指定了此 元数据 端点:
<!--This technical profile specifies how B2C should validate the token, and what claims you want B2C to extract from the token.
The METADATA value in the TechnicalProfile meta-data is required.
The “IdTokenAudience” and “issuer” arguments are optional (see later section)-->
<ClaimsProvider>
<DisplayName>ID Token Hint ClaimsProvider</DisplayName>
<TechnicalProfiles>
<TechnicalProfile Id="IdTokenHint_ExtractClaims">
<DisplayName>ID Token Hint TechnicalProfile</DisplayName>
<Protocol Name="None" />
<Metadata>
<!-- Action required: replace with endpoint location -->
<Item Key="METADATA">https://mywebsite.azurewebsites.net/.well-known/openid-configuration</Item>
<!-- <Item Key="IdTokenAudience">your_optional_audience_override</Item> -->
<!-- <Item Key="issuer">your_optional_issuer</Item> -->
</Metadata>
<OutputClaims>
<!--Read the email claim from the id_token_hint-->
<OutputClaim ClaimTypeReferenceId="email" />
<OutputClaim ClaimTypeReferenceId="shardTenantId"/>
</OutputClaims>
</TechnicalProfile>
</TechnicalProfiles>
</ClaimsProvider>
我的问题是:为什么会抛出这个 401(未经授权)?当我尝试访问元数据端点时:
https://mywebsite.azurewebsites.net/.well-known/openid-configuration
它打开得很好并返回所需的json
输出:
{
issuer: "https://mywebsite.azurewebsites.net/",
jwks_uri: "https://mywebsite.azurewebsites.net/.well-known/keys",
id_token_signing_alg_values_supported: [
"RS256"
]
}
这是输出上述
json
的 Web API 方法:
[AllowAnonymous]
[Route(".well-known/openid-configuration", Name = "OIDCMetadata")]
[HttpGet]
public HttpResponseMessage Metadata()
{
var json = JsonConvert.SerializeObject(new OidcModel
{
// The issuer name is the application root path
Issuer = InvitationHelper.GetBaseUrl(),
// Include the absolute URL to JWKs endpoint
JwksUri = Url.Link("JWKS", null),
// Sample: Include the supported signing algorithms
IdTokenSigningAlgValuesSupported = new[] { SigningCredentials.Value.Algorithm }
});
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;
}
我什至尝试向 API 方法添加 [AllowAnonymous] 注释,但这并没有做出任何改变。
为什么自定义注册邀请策略无法访问托管在不同 B2B AD 租户上的应用服务中的元数据端点?
注 1: 将 Application Insights 工具添加到此自定义策略中,我看到的唯一消息是致命异常 401,没有任何更有价值的信息:
{“种类”:“FatalException”,“内容”:{“时间”:“下午 4:15”,“异常”:
{“种类”:“已处理”,“HResult”:“80131500”,“消息”:“
元数据端点
'https://mywebsite.azurewebsites.net/.well-known/openid-configuration'
返回以下状态代码:
'401'","数据":
{"IsPolicySpecificError":false,"uri":"https://mywebsite.azurewebsites.net/.well-known/openid-configuration"}}}}
注 2: 如果您查看上面的
<ClaimsProvider>
,有以下 2 个设置:
<!-- <Item Key="IdTokenAudience">your_optional_audience_override</Item> -->
<!-- <Item Key="issuer">your_optional_issuer</Item> -->
我不确定如何使用其他 2 个设置,因为这些设置在 doc @ GitHub 中没有描述。
也许发行人是问题所在......我正在这里尝试,但到目前为止没有任何效果。所以我决定问这个问题。我希望有人能提供一些线索。
我通过 LinkedIn 与 Jas Suri 取得联系。他是在 GitHub 存储库中进行最后一次提交的人。
他向我询问真正的元数据端点(我在这里发布的是一个虚拟 URL)。
当他尝试访问该 URL 时,系统提示他登录......什么!?登录!?是的。这回答了问题。我的开发者盒子上有 SSO,这就是为什么我没有注意到这一点...但是等等:我在该 Web API 方法中有
[AllowAnonymous]
注释,对吗?那为什么还要求登录!?
他立即问我是否在应用程序服务级别启用了身份验证...我转到Azure Portal并检查了应用程序服务
Authorization/Authentication
设置。你猜怎么着……我把它打开了,但问题并不是那么直接。请参阅下面突出显示的设置:
我们可以保持它,但真正的问题是不久前我已经设置了
请求未经验证时采取的操作
使用 Azure Active Directory 登录
这会覆盖 Web API 方法上的
[AllowAnonymous]
注释。
当我在下拉列表中选择时:
允许匿名请求(无操作)
并保存,然后B2C策略开始按预期工作。
App Service 应用程序启用匿名访问。用户不会 提示登录。