我有一个配置了登录流程的 B2C 租户。我正在尝试验证从 Azure API 管理 (APIM) 内的 msal-Angular 接收的访问令牌,以便调用 Node.js API。但是,当向端点发出请求时,我遇到 401 Unauthorized 错误。我怀疑这个问题可能与范围有关,但我不确定。尽管设置了公开的 API 并定义了范围,我仍然无法使用有效的令牌访问 API 端点。
下面是Angular应用程序的代码。
let request = {
scopes: ['<tenantname>.onmicrosoft.com/<clientId>/access_as_user']
};
this.msalService.loginPopup(request).subscribe((response: AuthenticationResult) => {
this.msalService.instance.setActiveAccount(response.account);
// callNodeJsAPi with response.accessToken, here it gives 401
})
以下是APIM的代码。
<when condition="@( !(context.Variables.GetValueOrDefault<bool>(" isPublicEndpoint")) )">
<validate-jwt header-name="Authorization" failed-validation-httpcode="401"
failed-validation-error-message="Invalid credentials" require-scheme="Bearer" output-token-variable-name="jwt">
<openid-config
url="https:///<tenantname>.b2clogin.com/<tenantname>.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_sign_in" />
<audiences>
<audience>
<clientId>
</audience>
</audiences>
</validate-jwt>
<set-header name="userid" exists-action="override">
<value>@{
return ((Jwt)context.Variables["jwt"])?.Claims.GetValueOrDefault("name", "");
}</value>
</set-header>
</when>
我也检查了这个SO答案,并且很困惑,因为本文中提到的范围以api://开头,但对我来说它是tenant-name/clientid/scopename
我启用了 APIM 日志并检查了 APP Insights 正在获取
TokenInvalidIssuer: at validate-jwt
在 openid-config 中添加发行者解决了我的问题。解决 APIM 策略后应如下所示:
<when condition="@( !(context.Variables.GetValueOrDefault<bool>(" isPublicEndpoint")) )">
<validate-jwt header-name="Authorization" failed-validation-httpcode="401"
failed-validation-error-message="Invalid credentials" require-scheme="Bearer" output-token-variable-name="jwt">
<openid-config
url="https:///<tenantname>.b2clogin.com/<tenantname>.onmicrosoft.com/v2.0/.well-known/openid-configuration?p=B2C_1_sign_in" />
<openid-config url="https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>
<clientId>
</audience>
</audiences>
</validate-jwt>
<set-header name="userid" exists-action="override">
<value>@{
return ((Jwt)context.Variables["jwt"])?.Claims.GetValueOrDefault("name", "");
}</value>
</set-header>
</when>