【问题标题】:JWT Authentication returns 401 error on IISJWT 身份验证在 IIS 上返回 401 错误
【发布时间】:2020-06-22 23:10:24
【问题描述】:

我有一个使用 JWT 身份验证的 ASP.NET Core 3.1 API,该 API 旨在将资源发送到 Angular 项目。 某些方法受用户登录身份验证的保护。这适用于 Visual Studio 调试。但是在 IIS 上,我在这些方法中只得到 401 错误,即使 api 在登录时返回正确的令牌。

我不知道自己做错了什么,实际上我现在不知道自己在做什么。非常感谢任何有关 API 和 IIS 的帮助。

StartUp.cs

services.AddAuthentication(opt =>
            {
                opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,

                    ValidIssuer = "https://localhost:8080",
                    ValidAudience = "https://localhost:8080",
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("mySecretKey"))
                };
            });

appSettings.json

"iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false
  }

UserController.cs

[HttpPost("login")]
        public IActionResult Login([FromBody]User input)
        {
            if (input == null)
            {
                return BadRequest("Invalid client request");
            }

            var user = _context.Users.FirstOrDefault(ol => ol.Email == input.Email && ol.Password == input.Password);

            if (user != null)
            {
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("mySecretKey"));
                var signingCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

                var claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Email, user.Email),
                    new Claim(ClaimTypes.Role, user.Admin ? "Admin" : "NormalUser")
                };

                var tokenOptions = new JwtSecurityToken(
                    issuer: "https://localhost:8080",
                    audience: "https://localhost:8080",
                    claims: claims,
                    expires: DateTime.Now.AddHours(2),
                    signingCredentials: signingCredentials
                );

                var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);

                return Ok(new { Token = tokenString });
            }
            else
            {
                return Ok(new { Token = "Unauthorized" });
            }
        }

其他控制器示例方法

[Authorize(Roles = "Admin")]
        [HttpGet]
        public IActionResult Get()
        {
            try
            {
                doStuff();
            }
            catch (Exception e)
            {
                return BadRequest(e);
            }

            return Ok();
        }

【问题讨论】:

  • 问题可能出在这几行 ValidIssuer = "localhost:8080", ValidAudience = "localhost:8080" 我不知道您使用哪个地址来托管 IIS,但假设不是本地主机:8080。
  • 所以我 100% 确信它是正确的,因为我的 Angular applocation 在 8081 上运行,API 在 8080 上运行,此外,Angular 应用程序确实进行了成功的 api 调用,但只有调用不需要授权
  • 如果将 iisSettings 中的 windowsAuthentication 属性切换为 false 会发生什么?如果您使用令牌身份验证,则不需要 Windows 身份验证功能,除非您真的打算同时使用两者。
  • 如果您将应用程序发布到 IIS,首先应检查 IIS 管理控制台身份验证功能,确保启用了匿名身份验证并禁用了 windows 身份验证。

标签: c# asp.net-core iis jwt-auth


【解决方案1】:

我的朋友发现了我的问题!令牌从未添加到请求的 auth 标头中。我所做的只是使用 HTTP 拦截器将令牌添加到每个请求中。真正的问题是它在没有拦截器的情况下如何调试?

我想我们可以从中学到的是在运行到 StackOverflow 之前先检查您的标头。

我在 this question 上使用了 Martin Adámek 的回答。

【讨论】:

    猜你喜欢
    • 2019-09-13
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 2017-06-12
    • 2019-09-23
    • 2020-10-29
    • 2016-01-23
    相关资源
    最近更新 更多