英文:
When configuring JwtBearer or OpenIDConnect, Bearer error="invalid_token", c# .net 7
问题
以下是您的代码的翻译:
可以使用一些帮助来使 JwtBearer 或 OpenIdConnect 与 webapi 配合。
通常在配置应用程序时,我会寻找 OpenIdConnect 设置并按预期进行配置。这可以使我在多个应用程序中实现单点登录。我相信这应该排除 keycloak 作为可疑变量。
在下面的代码中,我得到了一个 302,经过了大量搜索后,我添加了```options.Events```,导致了当前的 401 错误:
< HTTP/2 401
< date: Sun, 26 Feb 2023 16:29:54 GMT
< content-length: 0
< www-authenticate: Bearer error="invalid_token"
< strict-transport-security: max-age=15724800; includeSubDomains
然而,我可以取出正在使用的令牌并将其复制到 jwt.io,它显示为有效。不确定为什么 webapi 在这里有困难。
当我进行测试时,我使用的是 swagger,点击身份验证,然后复制 'Bearer <token>' 并执行一个带有 '[Authorize]' 的方法。
增加日志级别后,我现在还看到:
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7]
Bearer was not authenticated. Failure message: No SecurityTokenValidator available for token.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
AuthenticationScheme: Bearer was challenged.
我已经更新了包。以下是代码片段:
Startup.cs
```csharp
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.MetadataAddress = Configuration.GetSection("appSettings")["auth0Domain"] + "/.well-known/openid-configuration";
options.Audience = Configuration.GetSection("appSettings")["auth0Audience"];
options.RequireHttpsMetadata = false;
options.IncludeErrorDetails = true;
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false
};
//添加更多配置
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
context.Token = context.Request.Headers["Authorization"];
return Task.CompletedTask;
},
};
});
IdentityModelEventSource.ShowPII = true;
// 配置跨域
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins()
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
//builder.WithOrigins("http://example.com",
// "http://www.contoso.com");
});
});
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Service service)
{
Globals.service = service;
service.Start();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// 启用中间件以提供生成的 Swagger 作为 JSON 端点。
app.UseSwagger();
// 启用中间件以提供 swagger-ui(HTML、JS、CSS 等),
// 指定 Swagger JSON 端点。
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
//app.UseHttpsRedirection();
app.UseRouting();
// 允许跨站调用
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
//app.UseMiddleware<ApiKeyMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseWebSockets();
// 处理传入的 Web 请求以启动 WebSockets
app.Use(async (context, next) => { await Globals.service.tm.HandleWebRequest(context, next); });
}
英文:
Could use a hand getting JwtBearer or OpenIdConnect working with a webapi.
Generally when configuring an app I look for OpenIdConnect settings and configure as expected. This works and I've got single signon working with several apps. I believe this should eliminate keycloak as a suspect variable.
With the code below I was getting a 302 and after much searching added in the options.Events
which led to the current 401 error:
< HTTP/2 401
< date: Sun, 26 Feb 2023 16:29:54 GMT
< content-length: 0
< www-authenticate: Bearer error="invalid_token"
< strict-transport-security: max-age=15724800; includeSubDomains
However, I can take the bearer token being used and copy it out to jwt.io and it shows as valid. Not sure why the webapi is struggling here.
When I test, I'm using the swagger, clicking on the authentication and copying in 'Bearer <token>' then Executing a method which has the '[Authorize]'.
After increasing log level I'm now also seeing:
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[7]
Bearer was not authenticated. Failure message: No SecurityTokenValidator available for token.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
AuthenticationScheme: Bearer was challenged.
I've updated packages. Here's the code snippet:
Startup.cs
services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.MetadataAddress = Configuration.GetSection("appSettings")["auth0Domain"] + "/.well-known/openid-configuration";
options.Audience = Configuration.GetSection("appSettings")["auth0Audience"];
options.RequireHttpsMetadata = false;
options.IncludeErrorDetails = true;
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false
};
//add more configs
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
context.Token = context.Request.Headers["Authorization"];
return Task.CompletedTask;
},
};
});
IdentityModelEventSource.ShowPII = true;
// Configure Cors
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins()
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
//builder.WithOrigins("http://example.com",
// "http://www.contoso.com");
});
});
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Service service)
{
Globals.service = service;
service.Start();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
// specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
//app.UseHttpsRedirection();
app.UseRouting();
// Allow cross-site calls
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
//app.UseMiddleware<ApiKeyMiddleware>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseWebSockets();
// Handle incoming webrequests in order to start WebSockets
app.Use(async (context, next) => { await Globals.service.tm.HandleWebRequest(context, next); });
}
答案1
得分: 0
你不应该需要添加 options.Events 部分,如果你通过通常的 Authorization: bearer 标头传递令牌。
我最近在这里1博客中写了有关排查 JwtBearer 问题的文章,希望能给你一些想法。请查看我的评论,了解要添加到你的问题中的其他内容。
英文:
You should not need to add the options.Events part, if you pass the token via the usual Authorization: bearer header.
I recently blogged about troubleshooting JwtBearer problems here and I hope that can give you some ideas. See my comments for additional things to add to your question.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论