Asp.net core 2 - 使用Bearer令牌出现401错误

15

使用ASP.NET Core生成的令牌授权后,我无法访问受保护的方法。

配置:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(cfg =>
            {
                cfg.RequireHttpsMetadata = false;
                cfg.SaveToken = true;
                cfg.Audience = Configuration["Tokens:Issuer"];
                cfg.ClaimsIssuer = Configuration["Tokens:Issuer"];
                cfg.TokenValidationParameters = new TokenValidationParameters()
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = Configuration["Tokens:Issuer"],
                    ValidAudience = Configuration["Tokens:Issuer"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"]))
                };

生成的令牌:

var claims = new[] {
                new Claim (JwtRegisteredClaimNames.Sub, model.Email),
                new Claim (JwtRegisteredClaimNames.Jti, Guid.NewGuid ().ToString()),
            };

            //_config
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Tokens:Key"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expiration = DateTime.UtcNow.AddDays(7);
            var token = new JwtSecurityToken(_config["Tokens:Issuer"],
                _config["Tokens:Issuer"],
                claims,
                expires: expiration,
                signingCredentials: creds);

            return new TokenModel()
            {
                Token = new JwtSecurityTokenHandler().WriteToken(token),
                Expiration = expiration,
                UserFirstName = model.FirstName,
                UserLastName = model.LastName
            };

在我生成之后,我得到了这种类型的令牌:

{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZWl4ZWlyYXBlcnNvQGdtYWlsLmNvbSIsImp0aSI6IjVmNTk3OGVkLWRlZjAtNDM3Yi1hOThhLTg3ZWU4YTQ3MmZlNCIsImV4cCI6MTUxODg2ODYxOCwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo1MDAwIn0.1fHXr8jtuZ8PTJmJPBKQIqiOk_c-bCQ6KRyFLLJkU5s",
    "expiration": "2018-02-17T11:56:58.683076Z",
    "userFirstName": null,
    "userLastName": null
}

我可以在 Postman 中添加或不添加授权的 HTTP 标头,但我收到了一个 "未经授权的异常 - 401"

我已经查看了一些其他的 Stack 帖子和 GitHub 帖子,似乎我的配置是正确的。

如果需要,我可以添加配置文件。

谢谢。

编辑 1:

这是 Postman 中标头的屏幕截图:

enter image description here


@DotNetDev 图片已添加 :) - OrcusZ
1
你确定使用相同的安全算法(HMACSHA256)来验证令牌吗?在.AddJwtBearer选项中没有指定它,因此它将使用默认算法,可能不是相同的算法。 - Brad
好的,我会检查。 - OrcusZ
1
好的,我移除了一些额外的配置,现在它可以工作了...谢谢大家。 - OrcusZ
2
@OrcusZ 不用管了,我搞定了 :) 只是删除了所有选项,保留了绝对最小的 issuersigningkey、validissuer 和 validaudience。 - hjavaher
显示剩余3条评论
2个回答

42

我不确定你是否遇到了同样的问题,但我正在运行一个类似于你的ASP.NET Core项目。

当我使用API登录提供的令牌时,遇到了401响应,但通过将app.UseAuthentication()作为Configure()方法的第一个方法调用来解决这个问题。我的代码从以下内容更改...

app.UseMvc();
app.UseAuthentication();

对于这件事……

app.UseAuthentication();
app.UseMvc();

3
你是救星!我浪费了几个小时来找出为什么它不起作用,结果只是调用的顺序问题! - Marcin
3
如果我能给你1万分,我就会这样做。这正是我的问题所在。 - Felix Cen
1
你真是个救命恩人。这个小改动让我浪费了两天时间。赞! - Kalana

7
你的代码看起来没有问题。问题最可能的根本原因是你没有将身份验证中间件添加到应用程序。对于IServiceCollection,AddAuthentication扩展调用只注册所有所需的服务,但它不会将身份验证中间件添加到HTTP请求管道中。
为了解决这个问题,请在Startup.Configure()方法中添加以下调用:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseAuthentication();

    // ...
}

我能够使用你的代码重现问题,调用app.UseAuthentication() 可以解决这个问题。


嗯,那么我无法重现你的问题。如果调用了 app.UseAuthentication(),我已经复制/粘贴了你的代码,认证就可以正常工作。 - CodeFuller
嗯...我想我没有说过,但我正在macOS系统中运行此代码,我不知道这是否可能是问题的根源。 - OrcusZ
你有机会在Windows上启动它吗?这将有助于缩小可能的根本原因。 - CodeFuller
是的。我会在Windows系统上正确测试之后返回结果 :) - OrcusZ
@OrcusZ 你有没有找到问题的解决办法?我现在正处于完全相同的情况。 - hjavaher
@hjavaher 这是我的配置错误。请发布一个新的问题,我会查看。 - OrcusZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接