我使用 React 在前端通过 EntraId 授权用户。这很好用,但现在我想通过授权标头将 accessToken 发送到后端,这也有效。 现在后端需要检查Token,事情开始变得复杂。 首先,我收到错误 401(未经授权),其中包含“WWW-Authenticate”-标头(响应标头)
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid
.
后端显示此错误:
info: Microsoft.IdentityModel.LoggingExtensions.IdentityLoggerAdapter[0]
IDX10243: Reading issuer signing keys from validation parameters.
info: Microsoft.IdentityModel.LoggingExtensions.IdentityLoggerAdapter[0]
IDX10265: Reading issuer signing keys from configuration.
info: Microsoft.IdentityModel.LoggingExtensions.IdentityLoggerAdapter[0]
IDX10243: Reading issuer signing keys from validation parameters.
fail: Microsoft.IdentityModel.LoggingExtensions.IdentityLoggerAdapter[0]
IDX10511: Signature validation failed. Keys tried: 'Microsoft.IdentityModel.Tokens.X509SecurityKey, KeyId: '3PaK4EfyBNQu3CtjYsa3YmhQ5E0', InternalId: '3PaK4EfyBNQu3CtjYsa3YmhQ5E0'. , KeyId: 3PaK4EfyBNQu3CtjYsa3YmhQ5E0
'.
Number of keys in TokenValidationParameters: '0'.
Number of keys in Configuration: '8'.
Matched key was in 'Configuration'.
kid: '3PaK4EfyBNQu3CtjYsa3YmhQ5E0'.
Exceptions caught:
'[PII of type 'System.String' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
token: '[PII of type 'Microsoft.IdentityModel.JsonWebTokens.JsonWebToken' is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'. See https://aka.ms/IDX10511 for details.
我已经尝试更改配置:
/*builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration);*/
/*builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration, "AzureAd");
*/
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
/*builder.Services.AddAuthorization(config =>
{
config.AddPolicy("AuthZPolicy", policyBuilder =>
policyBuilder.Requirements.Add(new ScopeAuthorizationRequirement() { RequiredScopesConfigurationKey = $"AzureAd:Scopes" }));
});*/
未注释的也是尝试过,但没有成功。
accessToken是用axios发送的:
axios.interceptors.request.use(async config => {
const authToken = await instance.acquireTokenSilent({
scopes: ['openid', 'profile', 'email']
});
console.log(authToken.accessToken);
const accessToken = authToken.accessToken;
config.headers.Authorization = `Bearer ${accessToken}`;
return config;
});
我已经尝试了一切可能的方法,但错误仍然存在。
我相信您的身份验证和生成访问令牌的代码是正确的,因为您已经能够生成访问令牌。而且后端API的配置看起来也不错。您的问题与您使用的范围有关。
这里是使用 Azure AD 保护我们自己的 Web api 的 教程 。就像您在公开委托权限(范围)/公开应用程序权限(应用程序角色)部分中看到的那样,需要创建自定义 api 权限,然后我们可以在代码中使用
api://client_id_exposing_api/permision_name
作为范围。顺便说一句,您只能创建一个 Azure AD 应用程序来完成所有任务(exponse API、授予 API 权限、创建客户端密钥/证书,并在 React 前端和 .Net core Web api 后端使用它们)。这是一些样本。
我们可以使用 VS2022 创建一个新的 .net core Web api,并选择 Microsoft Identity Platform 作为身份验证类型,以获得已由 Azure AD 保护的准备好的 API 项目。只需更改 appsetting.json 中的配置,它应该类似于:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "clientid_which_have_api_permission",
"Domain": "tenantname.onmicrosoft.com",
"TenantId": "common",
"Audience": "api://clientid_of_the_app_exposed_api"
}
在Program.cs中,您只需要以下代码即可。
EnableTokenAcquisitionToCallDownstreamApi().AddInMemoryTokenCaches();
用于 ITokenAcquisition
生成访问令牌,但不用于验证授权。
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration, "AzureAd");