我关注了Microsofts article实现我自己的发行者验证(“自定义 token 验证”是本节的标题)。
这似乎适用于在仅应用程序上下文中颁发的 JWT token ,但当第一次调用我的 API 是通过用户委托(delegate)颁发的 JWT token 时失败.
我发现这行代码导致了问题:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(Configuration);
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
var existingOnTokenValidatedHandler = options.Events.OnTokenValidated;
options.Events.OnTokenValidated = async context =>
{
await existingOnTokenValidatedHandler(context);
// Your code to add extra configuration that will be executed after the current event implementation.
options.TokenValidationParameters.ValidIssuers = new[] { /* list of valid issuers */ };
options.TokenValidationParameters.ValidAudiences = new[] { /* list of valid audiences */};
}
});
这是我上面发布的链接中的原始代码。 我通过以下方式实现了自己的发行人验证:
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
var existingOnTokenValidatedHandler = options.Events.OnTokenValidated;
options.TokenValidtionParameters.RoleClaimType = "roles";
options.Events.OnTokenValidated = async context =>
{
await existingOnTokenValidatedHandler(context);
options.Authority = "https://login.microsoftonline.com/common";
var validTenants = FileTenantStore.Tenants.Select(x => x.AzureAdTenantId).ToList();
options.TokenValidationParameters.ValidIssuers = GetValidIssuers(validTenants);
options.TokenValidationParameters.IssuerValidator = ValidateIssuers;
};
});
我有一个 Multi-Tenancy 应用程序,因此我需要只让一些租户通过并拒绝最多的租户。
这个解决方案的行为有点奇怪:
- 使用仅应用 token 调用 API 始终有效。
- 使用委托(delegate) token 调用 API 失败,并显示以下错误消息,甚至不会跳转到回调:
Failed to validate the token. Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDW10303: Issuer: 'https://login.microsoftonline.com/{OUR_TENANT_ID}/v2.0', does not match any of the valid issuers provided for this application. at Microsoft.Identity.Web.Resource.AadIssuerValidator.Validate(String actualIssuer, SecurityToken securityToken, TokenValidationParameters validationParameters) at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateIssuer(String issuer, JwtSecurityToken jwtToken, TokenValidationParameters validationParameters) at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters validationParameters) at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken) at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
因此,在这种情况下,“OnTokenValidated”永远不会被调用。
- 第一次使用仅应用 token 调用 API,然后使用委托(delegate) token 调用 API,效果很好。
我可以通过将“OnTokenValidated”回调中的行移至上一级来解决此问题:
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
var existingOnTokenValidatedHandler = options.Events.OnTokenValidated;
options.TokenValidationParameters.RoleClaimType = "roles";
var validTenants = FileTenantStore.Tenants.Select(x => x.AzureAdTenantId).ToList();
options.TokenValidationParameters.ValidIssuers = GetValidIssuers(validTenants);
options.TokenValidationParameters.IssuerValidator = ValidateIssuers;
options.Events.OnTokenValidated = async context =>
{
await existingOnTokenValidatedHandler(context);
options.Authority = "https://login.microsoftonline.com/common";
};
});
我现在甚至可以删除回调“OnTokenValidated”,但这感觉不对,因为 Microsoft 文章给出了明确的说明。
我可以这样做吗,还是我的解决方案存在安全问题?
最佳答案
如果您在 netcore>3 中,您可以使用 AddMicrosoftIdentityWebApiAuthentication 扩展方法。将 subscribeToOpenIdConnectMiddlewareDiagnosticsEvents 设置为 true 并启用调试日志记录以查看终止特定 token 检查的事件。
根据您的代码:
services.AddMicrosoftIdentityWebApiAuthentication(Configuration,
jwtBearerScheme: JwtBearerDefaults.AuthenticationScheme,
subscribeToJwtBearerMiddlewareDiagnosticsEvents: true);
关于Azure 身份 : Custom token validation to validate issuers in a multi tenant app,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66506014/