我按照 Microsofts article 实现了我自己的颁发者验证(“自定义令牌验证”是该部分的标题)。
这似乎适用于在仅限应用上下文中发布的 JWT 令牌,但是当第一次调用我的 API 是通过用户委托发布的 JWT 令牌时失败了.
我发现这行代码导致了问题:
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;
};
});
我有一个多租户应用,所以我只需要让一些租户通过并拒绝最多。
这个解决方案有点奇怪:
无法验证令牌。 Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDW10303:发行人: 'https://login.microsoftonline.com/{OUR_TENANT_ID}/v2.0', 与为此应用程序提供的任何有效发行人都不匹配。 在 Microsoft.Identity.Web.Resource.AadIssuerValidator.Validate(String actualIssuer、SecurityToken securityToken、TokenValidationParameters 验证参数) 在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateIssuer(String 发行者,JwtSecurityToken jwtToken,TokenValidationParameters 验证参数) 在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateTokenPayload(JwtSecurityToken jwtToken, TokenValidationParameters 验证参数) 在 System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String 令牌, TokenValidationParameters 验证参数, SecurityToken& 验证令牌) 在 Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
所以在这种情况下,“OnTokenValidated”从不被调用。
我可以通过将“OnTokenValidated”-Callback 中的行移动到上一层来解决这个问题:
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”,但这感觉不对,因为微软的文章给出了明确的说明。
我可以这样做吗,还是我的解决方案存在安全问题?
答案 0 :(得分:1)
如果你在 netcore>3 你可以使用 AddMicrosoftIdentityWebApiAuthentication 扩展方法。将 subscribeToOpenIdConnectMiddlewareDiagnosticsEvents 设置为 true 并启用调试日志记录以查看终止特定令牌检查的事件。
基于您的代码:
services.AddMicrosoftIdentityWebApiAuthentication(Configuration,
jwtBearerScheme: JwtBearerDefaults.AuthenticationScheme,
subscribeToJwtBearerMiddlewareDiagnosticsEvents: true);