Asp.net core 2 - 不记名令牌出现 401 错误

Posted

技术标签:

【中文标题】Asp.net core 2 - 不记名令牌出现 401 错误【英文标题】:Asp.net core 2 - 401 error with bearer token 【发布时间】:2018-07-21 02:10:50 【问题描述】:

我无法使用由 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:

这里是邮递员的标题屏幕:

【问题讨论】:

您的授权标头看起来如何? @DotNetDev 图片已添加 :) 您确定使用相同的安全算法 (HMACSHA256) 来验证令牌吗?您没有在 .AddJwtBearer 选项中指定它,因此它将使用可能不是相同算法的默认值。 好的,所以我删除了一些额外的配置,它的工作原理......谢谢伙计们 @OrcusZ 没关系,我明白了 :) 只是删除了所有选项并保留了绝对最小值,即 issuersigningkey、validissuer 和 validaudience。 【参考方案1】:

我不确定您是否面临同样的问题,但我正在运行一个 ASP.NET Core 项目,其代码与您的相似。

当包含 API 登录提供的不记名令牌时,我遇到了 401 响应,但通过在 Configure() 中将 app.UseAuthentication() 作为 first 方法调用来解决此问题。我的代码从这里改变了......

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

到这里……

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

【讨论】:

你是救星!我只是浪费了几个小时来弄清楚为什么它不起作用,而这只是调用顺序! 如果我能给你10000分我会的。这正是我的问题。【参考方案2】:

您的代码看起来不错。问题最可能的根本原因是您没有向应用程序添加身份验证中间件。 AddAuthenticationIServiceCollection 的扩展调用只是注册了所有需要的服务,但它没有将身份验证中间件添加到 HTTP 请求管道。

要解决此问题,请在 Startup.Configure() 方法中添加以下调用:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)

    app.UseAuthentication();

    // ...

我能够用您的代码重现该问题,并调用 app.UseAuthentication() 解决了该问题。

【讨论】:

嗯,那么我无法重现您的问题。如果调用app.UseAuthentication(),我已经复制/粘贴了您的代码并且身份验证工作正常。 嗯...我好像没有告诉它,但是我在macOS系统中运行这段代码,我不知道这是否是问题的根源 你有机会在 Windows 上启动它吗?这将有助于缩小可能的根本原因。 是的。当我在 Windows 系统中正确测试它时,我会这样做并返回 :) @OrcusZ 大家有没有发现问题?我现在的情况完全一样。

以上是关于Asp.net core 2 - 不记名令牌出现 401 错误的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.NET Core 2.1 Web 客户端中存储不记名令牌的位置

如何在 Asp .Net Core SignalR Hub 中获取不记名令牌?

ASP.NET Core API 使用 JWT 不记名令牌进行身份验证

JWT不记名令牌授权不起作用asp net core web api

JWT 不记名令牌不适用于 ASP.Net Core 3.1 + Identity Server 4

即使在 asp.net core 5.0 中提供了不记名令牌,也会返回 401 [关闭]