在配置 JwtBearer 或 OpenIDConnect 时,Bearer 错误=”invalid_token”,c# .net 7

huangapple go评论94阅读模式
英文:

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 =&gt;
{
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =&gt;
{
    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 =&gt;
        {
            context.Token = context.Request.Headers["Authorization"];
            return Task.CompletedTask;
        },
    };
});

IdentityModelEventSource.ShowPII = true;

// 配置跨域
services.AddCors(options =&gt;
{
    options.AddDefaultPolicy(
        builder =&gt;
        {
            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 =&gt;
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

    //app.UseHttpsRedirection();

    app.UseRouting();

    // 允许跨站调用
    app.UseCors();

    app.UseAuthentication();
    app.UseAuthorization();
    //app.UseMiddleware&lt;ApiKeyMiddleware&gt;();

    app.UseEndpoints(endpoints =&gt;
    {
        endpoints.MapControllers();
    });

    app.UseWebSockets();

    // 处理传入的 Web 请求以启动 WebSockets
    app.Use(async (context, next) =&gt; { 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:

    &lt; HTTP/2 401
    &lt; date: Sun, 26 Feb 2023 16:29:54 GMT
    &lt; content-length: 0
    &lt; www-authenticate: Bearer error=&quot;invalid_token&quot;
    &lt; 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 =&gt;
    {
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(options =&gt;
    {
        options.MetadataAddress = Configuration.GetSection(&quot;appSettings&quot;)[&quot;auth0Domain&quot;] + &quot;/.well-known/openid-configuration&quot;;
        options.Audience = Configuration.GetSection(&quot;appSettings&quot;)[&quot;auth0Audience&quot;];
        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 =&gt;
            {
                context.Token = context.Request.Headers[&quot;Authorization&quot;];
                return Task.CompletedTask;
            },
        };
    });

    IdentityModelEventSource.ShowPII = true;


    // Configure Cors
    services.AddCors(options =&gt;
    {
        options.AddDefaultPolicy(
            builder =&gt;
            {
                builder.WithOrigins()
                        .AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader();
                //builder.WithOrigins(&quot;http://example.com&quot;,
                //                    &quot;http://www.contoso.com&quot;);
            });
    });
        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 =&gt;
            {
                c.SwaggerEndpoint(&quot;/swagger/v1/swagger.json&quot;, &quot;My API V1&quot;);
            });

            //app.UseHttpsRedirection();

            app.UseRouting();

            // Allow cross-site calls
            app.UseCors();

            app.UseAuthentication();
            app.UseAuthorization();
            //app.UseMiddleware&lt;ApiKeyMiddleware&gt;();

            app.UseEndpoints(endpoints =&gt;
            {
                endpoints.MapControllers();
            });

            app.UseWebSockets();

            // Handle incoming webrequests in order to start WebSockets
            app.Use(async (context, next) =&gt; { 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.

huangapple
  • 本文由 发表于 2023年2月27日 00:56:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75573577.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定