调用授权方法时 JWTBearer 错误

JWTBearer error on calling authorized method

我正在为小型本机移动应用程序开发移动 REST API。 我的麻烦是 JWT 在汇编 Microsoft.AspNetCore.Authentication.JwtBearer, Version=3.0.2.0

我在 startup.cs 方法 ConfigureServices 中的设置:

services.AddAuthentication()
            .AddJwtBearer(CommonHelper.MobileApiConstant.AuthSchemaName, options =>
                {
                    options.SaveToken = true;
                    options.IncludeErrorDetails = true;
                    options.RequireHttpsMetadata = true;
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        IssuerSigningKey =
                            new SymmetricSecurityKey(
                                CommonHelper.MobileApiConstant.GetSymmetricSecurityKeyByteArray(_customerCodeConfiguration.CustomerCode)),
                        ValidateIssuerSigningKey = false,
                        ValidateIssuer = false,
                        ValidateAudience = false,
                    };
                });

我的 API 控制器是:

[Route(CommonHelper.MobileApiConstant.RouteName + "/[controller]/[action]")]
    [ApiController]
    [Authorize(AuthenticationSchemes = CommonHelper.MobileApiConstant.AuthSchemaName)]
    [ApiVersion("1")]
    public class AuthenticationController : Controller
    {
        [HttpGet]
        [AllowAnonymous]
        [ProducesResponseType(typeof(ResultModel<IMobileCrmUser>), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        public async Task<IActionResult> Authenticate([NotNull] string userName, [NotNull] string password)
        {
            if (!IsOk) // some usless logic 
            {
                return Unauthorized();
            }

            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
            byte[] key = CommonHelper.MobileApiConstant.GetSymmetricSecurityKeyByteArray("My private string");

            SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Expires = DateTime.UtcNow.AddDays(14),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };
            SecurityToken token = tokenHandler.CreateToken(tokenDescriptor);

            return Ok(tokenHandler.WriteToken(token));
        }

        [HttpGet]
        [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        public IActionResult TestMethodGet(string test)
        {
            if (test == nameof(test))
                return Ok("succes");
            else
                return BadRequest("bad");
        }
    }

当我调用方法 Authenticate (Allow anonymous) 时一切正常:

curl -X GET "https://localhost:5001/MobileApi/Authentication/Authenticate?userName=mail%40mail.cz&password=password" -H "accept: text/plain" -H "x-api-version: 1"

令牌已返回。然后我想调用 TestMethodGet 方法请求是:

curl -X GET "https://localhost:5001/MobileApi/Authentication/TestMethodGet?test=test" -H "accept: text/plain" -H "x-api-version: 1" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImR2ZXNlbHlAY2VudHJ1bS5jeiIsIm5hbWVpZCI6IjIiLCJyb2xlIjpbIkFkbWluIiwiQnVzaW5lc3MiXSwibmJmIjoxNTg3MDMxOTAwLCJleHAiOjE1ODgyNDE1MDAsImlhdCI6MTU4NzAzMTkwMH0.rb_0nxWqedmruaBiaivd8ZrQBBi9SNcgsEQlqrOxhAo"

响应是:

content-length: 0 
 date: Thu, 16 Apr 2020 10:13:51 GMT 
 server: Kestrel 
 status: 401 
 www-authenticate: Bearer 

我不知道错误在哪里,也不知道为什么服务器不给我写更多信息。 API 调用是通过 Swagger 进行的。

我尝试设置 options.IncludeErrorDetails = true;但结果相同。

感谢您的帮助

您需要在 Authorization header 中添加单词 Bearer:

Authorization: Bearer eyJhbGciOi..

那么应该可以了。


在回复中

content-length: 0 
date: Thu, 16 Apr 2020 10:13:51 GMT 
server: Kestrel 
status: 401 
www-authenticate: Bearer 

您不仅可以看到状态,在本例中为 401,还可以看到响应 header

www-authenticate: Bearer 

根据 RFC1945 告诉你使用哪个方案:

The field value consists of at least one challenge that indicates the authentication scheme(s) and parameters applicable to the Request-URI.

因此,在这种情况下是 Bearer 方案。

Bearer 是实现 OAuth2.0 授权协议的 standard 方案。

另见 this Q/A