IClaimsTransformation未为带身份验证的GraphQL启动.JwtBearer v6



更新

以下日志消息可能是的根本原因

System.MissingMethodException: Method not found: 'Void Microsoft.IdentityModel.Tokens.InternalValidators.ValidateLifetimeAndIssuerAfterSignatureNotValidatedJwt(Microsoft.IdentityModel.Tokens.SecurityToken, System.Nullable`1<System.DateTime>, System.Nullable`1<System.DateTime>, System.String, Microsoft.IdentityModel.Tokens.TokenValidationParameters, System.Text.StringBuilder)'.n  
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateSignature(String token, TokenValidationParameters validationParameters)n   
at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.ValidateToken(String token, TokenValidationParameters validationParameters, SecurityToken& validatedToken)n   
at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()",

原始帖子

我们有一个项目,其中我们使用IClaimsTransformation实现来修改JWT中的角色。这对于我们使用Microsoft.AspNetCore.Authentication.JwtBearer v5.0.12包的服务的传统HTTP端点和GraphQL端点都很好。

当我们将此包更新到版本6.0.0时,它将停止为GraphQL端点工作。这是因为包中有一个已知的更改(我找不到任何信息(,还是一个bug?如果这是预期的,我们如何让它再次发挥作用?

所有包裹清单:

<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.2.0" />
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.1" />
<PackageReference Include="GraphQL.Conventions.NodaTime" Version="1.0.1" />
<PackageReference Include="GraphQL.Relay" Version="0.6.2" />
<PackageReference Include="GraphQL.Server.Authorization.AspNetCore" Version="5.1.1" />
<PackageReference Include="GraphQL.Server.Transports.AspNetCore" Version="5.1.1" />
<PackageReference Include="GraphQL.Server.Transports.AspNetCore.SystemTextJson" Version="5.1.1" />
<PackageReference Include="GraphQL.Server.Ui.Altair" Version="5.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.12" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />

配置服务

services.AddControllers();
services.AddGraphQL(
(options, provider) =>
{
var logger = provider.GetRequiredService<ILogger<Startup>>();
options.UnhandledExceptionDelegate = ctx =>
{
logger.LogError(ctx.OriginalException, "Unhandled exception in graphQL");
// CloudPrint specific exception unlikely to leak sensitive information in its message
if (ctx.OriginalException.GetType().FullName!.StartsWith("CloudPrint."))
ctx.ErrorMessage = ctx.OriginalException.Message;
var requestId = GetRequestId(ctx);
if (requestId != null)
ctx.Exception.Data["RequestId"] = requestId;
};
})
// Adds all graph types in the current assembly with a singleton lifetime.
.AddGraphTypes()
.AddDataLoader()
.AddSystemTextJson()
.AddGraphQLAuthorization(options =>
{
options.AddPolicy("create", p => p.RequireRole("create"));
// other policies removed to reduce size of post
});
services.AddTransient<IValidationRule, AuthorizationValidationRule>();
services.AddTransient(typeof(ConnectionType<>))
.AddTransient(typeof(EdgeType<>))
.AddTransient<NodeInterface>()
.AddTransient<PageInfoType>();
services.AddSingleton<IClaimsTransformation, ClaimsTransformer>(); // <------ Our transformation implementation
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", options => { })
.AddJwtBearer(config =>
{
config.Authority = Configuration["Jwt:Authority"];
config.Audience = Configuration["Jwt:Audience"];
config.TokenValidationParameters = new TokenValidationParameters()
{
ValidateAudience = true
};
}); 
services.AddAuthorization(options =>
{
options.AddPolicy("BasicAuthentication", new AuthorizationPolicyBuilder("BasicAuthentication").RequireAuthenticatedUser().Build());
});

注意,我没有包含ClaimsTransformer的代码,因为我已经在调试器中观察到TransformAsync方法从未被调用,因此它的实现无关紧要。

事实证明,Microsoft.IdentityModel.Tokens 6.15.0中似乎确实缺少InternalValidators.ValidateLifetimeAndIssuerAfterSignatureNotValidatedJwt,将此包降级为6.14.1解决了问题。

挖得更深一点看起来是这个问题

最新更新