【问题标题】:How to customize bearer header keyword in asp.net core for JwtBearer and System.IdentityModel.Tokens.Jwt?如何在 asp.net 核心中为 JwtBearer 和 System.IdentityModel.Tokens.Jwt 自定义不记名头关键字?
【发布时间】:2019-11-13 10:08:43
【问题描述】:

使用using Microsoft.AspNetCore.Authentication.JwtBearer;我一直无法弄清楚如何将标题中的“Bearer”键更改为其他内容,在这种情况下,我希望它是“Token”。

Startup.cs

services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(x =>
             {
                 x.RequireHttpsMetadata = false;
                 x.SaveToken = true;
                 x.TokenValidationParameters = new TokenValidationParameters
                 {
                     ValidateIssuerSigningKey = true,
                     IssuerSigningKey = new SymmetricSecurityKey(key),
                     ValidateIssuer = false,
                     ValidateAudience = false,
                     ValidateLifetime = true,
                     ValidIssuer = Configuration.GetValue<string>("JwtIssuer"),
                     ValidAudience = Configuration.GetValue<string>("JwtAudience"),
                 };
                 x.Events = new JwtBearerEvents
                 {
                     OnAuthenticationFailed = context =>
                     {
                         if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                         {
                             context.Response.Headers.Add("Token-Expired", "true");
                         }
                         return Task.CompletedTask;
                     }
                 };
             });

当我做类似的事情时

GET {{protocol}}://{{url}}/users HTTP/1.1
Authorization: Bearer {{token}}

令牌有效,但我不知道如何将其自定义为类似的东西。

GET {{protocol}}://{{url}}/users HTTP/1.1
Authorization: Token {{token}}


【问题讨论】:

    标签: c# asp.net-core .net-core bearer-token


    【解决方案1】:

    JwtBearer 身份验证处理程序的实现位于JwtBearerHandler 内部,其中Authorization 标头使用Bearer ... 格式读取和拆分。看起来是这样的:

    string authorization = Request.Headers["Authorization"];
    
    // If no authorization header found, nothing to process further
    if (string.IsNullOrEmpty(authorization))
    {
        return AuthenticateResult.NoResult();
    }
    
    if (authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
    {
        token = authorization.Substring("Bearer ".Length).Trim();
    }
    
    // If no token found, no further work possible
    if (string.IsNullOrEmpty(token))
    {
        return AuthenticateResult.NoResult();
    }
    

    如上面的代码所示,这是硬编码为使用Bearer。但是,JwtBearerEvents 包含一个 OnMessageReceived 属性,它允许您连接到从传入请求中检索 JWT 的过程。如果您为此事件提供了实现,则可以使用自己的处理来提取 JWT,但您愿意。

    从上面的实现中进行一些更改,事件处理程序实现会像这样:

    x.Events = new JwtBearerEvents
    {
        // ...
        OnMessageReceived = context =>
        {
            string authorization = context.Request.Headers["Authorization"];
    
            // If no authorization header found, nothing to process further
            if (string.IsNullOrEmpty(authorization))
            {
                context.NoResult();
                return Task.CompletedTask;
            }
    
            if (authorization.StartsWith("Token ", StringComparison.OrdinalIgnoreCase))
            {
                context.Token = authorization.Substring("Token ".Length).Trim();
            }
    
            // If no token found, no further work possible
            if (string.IsNullOrEmpty(context.Token))
            {
                context.NoResult();
                return Task.CompletedTask;
            }
    
            return Task.CompletedTask;
        }
    };
    

    【讨论】:

      【解决方案2】:

      前缀Bearer ... 来自您设置为默认身份验证方案的JwtBearerDefaults.AuthenticationScheme

      如果你愿意,你可以使用 custom authentication 这样或类似的:

      // Add authentication
      services.AddAuthentication(options =>
      {
          options.DefaultAuthenticateScheme = CustomAuthOptions.DefaultScheme;
          options.DefaultChallengeScheme = CustomAuthOptions.DefaultScheme;
      })
      // Call custom authentication extension method
      .AddCustomAuth(options =>
          {
          // Configure password for authentication
          options.AuthKey = "custom auth key";
      });
      

      .. 或者甚至可以将custom scheme name.AddJwtBearer(x =&gt; ...) 结合起来——从未尝试过。或者您可能只是在寻找类似protecting your API with API Keys 的东西。

      【讨论】:

      • 我不是在尝试硬编码 api 密钥,而是在标题中更改 bearer 关键字,例如authorization: header xxxauthorization: token xxx
      • 我明白了。请参阅“Prefix Bearer ...来自 JwtBearerDefaults.AuthenticationScheme”,它只是“Bearer”字符串常量。我怀疑这个常量值在 auth 中间件中使用,但你也许可以尝试将“Token”字符串设置为方案名称,然后使用相同的 .AddJwtBearer(x =&gt; ...) 配置。
      • 我尝试将token设置为各种组合的方案名称,但没有成功
      • 我明白了。因此,您似乎需要同意使用 Bearer,或者实现自己的类似承载的身份验证 custom authentication,它将根据需要使用 Token 前缀。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      • 2019-10-05
      • 2019-05-23
      相关资源
      最近更新 更多