【问题标题】:separately created JWT not getting authorized in asp.net core单独创建的 JWT 未在 asp.net 核心中获得授权
【发布时间】:2020-08-19 12:06:25
【问题描述】:

我有一个场景,我必须在 javascript 应用程序中手动创建 JWT,所以我在这里使用了代码

https://codepen.io/jpetitcolas/pen/zxGxKN

在我的 asp.net 核心中,我有一个简单的值控制器,其函数装饰有 Authorize

[Authorize]
    [Route("GetValues")]
    [HttpGet]
    public IEnumerable<string> GetValues()
    {
        return new string[] { "value1", "value2" };
    }

在我的 startup.cs 中有

       public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = false;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("My very confidential secret!!!")),
                    ValidateIssuerSigningKey = true,
                    ValidateLifetime = false, //set this to true when a reasonable lifetime has been determined based on jwt generation
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });
        services.AddControllers();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseAuthentication();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

如您所见,我在令牌中使用相同的秘密并尝试在 asp.net 核心中进行验证,但是当我使用 post man 调用 https://localhost:44364/GetValues 并将授权密钥设置为“Bearer”时,我得到 401-未经授权。我错过了什么吗?

知道我在这里可能做错了什么。

更新

 public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {            
        // services.AddAuthorization();
        services.AddControllers();

        // var hmac = new HMACSHA256(System.Text.Encoding.ASCII.GetBytes("My very confidential secret!!!"));
        // var symKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(hmac.Key);

        var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("My very confidential secret!!!"));
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256Signature);

        services.AddAuthentication(opt =>
        {
            opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddJwtBearer(options =>
        {
            options.RequireHttpsMetadata = false;
            options.SaveToken = true;
            options.TokenValidationParameters = new TokenValidationParameters()
            {
                ValidateIssuer = false,
                ValidateAudience = false,
                ValidateLifetime = false,
                ValidateIssuerSigningKey = true,
                ClockSkew = System.TimeSpan.Zero,
                IssuerSigningKey = signinCredentials.Key
            };
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // app.UseMiddleware<AuthenticationMiddleware>();
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            // ...
            app.UseHsts();
        }
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthentication(); // this one first
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

更新 2

即使我设置 ValidateIssuerSigningKey = false 意味着我什至不想验证密钥,即使我得到 401 Unauthorized 。 重新创建我们可以创建一个带有示例值控制器的空白 .net core api 项目,然后复制粘贴我的 Startup.cs,然后是来自 https://codepen.io/jpetitcolas/pen/zxGxKN 的不记名令牌 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTMzNywidXNlcm5hbWUiOiJqb2huLmRvZSJ9.EvTdOJS-fbffGHLyND3BMDwWE22zUBOCRspPZEHlNEw

最后就是这样使用邮递员

【问题讨论】:

  • 首先将app.UseAuthentication();放在app.UseRouting();app.UseAuthorization();之间,然后使用fiddler跟踪请求,检查WWW-Authenticate header是否有错误。
  • 现在我在这个序列中使用它们 app.UseRouting(); app.UseAuthentication(); // 这是第一个 app.UseAuthorization();我现在会检查提琴手。
  • 标题似乎没问题我正在发送承载 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTMzNywidXNlcm5hbWUiOiJqb2huLmRvZSJ9.DgYz3ZaZiKThbpHj2Bg44cdGqdPm3QwrJp 令牌
  • 我说的是401码返回时的响应头(WWW-Authenticate)。
  • www-authenticate →Bearer error="invalid_token", error_description="签名无效"

标签: asp.net-core authentication jwt


【解决方案1】:

您没有使用相同的签名密钥,在您的 js 小提琴中,您有一个字符串作为密钥,并且在您的验证中您期望对称密钥。

在 js 中,您有以下行,其中 secret 是您的签名密钥:

签名 = CryptoJS.HmacSHA256(签名,秘密);

使用秘密作为签名密钥应该可以解决问题。

【讨论】:

  • 我使用了 IssuerSigningKey = HMACSHA256(Encoding.ASCII.GetBytes(mySecret));在我的 startup.cs 代码中,但问题是“IssuerSigningKey”需要“SecurityKey”的类型。我的想法?
  • 我像这样生成了 HMACSHA256 var hmac = new HMACSHA256(System.Text.Encoding.ASCII.GetBytes("MySecret")); var symKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(hmac.Key);并将其传递给“IssuerSigningKey”。没用
  • 在您的签名上,您可以尝试使用 SecurityAlgorithms.HmacSha256Signature 吗?
  • 我改了但是还是得到401未授权的“Bearer error="invalid_token", error_description="签名无效""
  • 好的,我回家后在本地试试。
猜你喜欢
  • 2020-02-16
  • 1970-01-01
  • 2020-09-10
  • 2018-09-10
  • 2020-08-20
  • 2022-01-17
  • 2020-04-28
  • 2021-08-07
  • 2019-05-01
相关资源
最近更新 更多