Ошибка JWTBearer при вызове авторизованного метода

Я разрабатываю мобильный 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 (разрешить анонимность), все в порядке:

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; но с тем же результатом.

спасибо за помощь


person Davecz    schedule 16.04.2020    source источник
comment
изменить заголовок на Authorization: Bearer eyJhbGciOi...   -  person jps    schedule 16.04.2020
comment
curl -X GET localhost:5001/MMobileApi/Authentication/ -H accept: text/plain -H x-api-version: 1 -H Authorization Bearer: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImR2ZXNlbHlAY2VudHJ1bS5jeiIsIm5hbWVpZCI6IjIiLCJyb2xlIjpbIkFkbWluIiwiQnVzaW5lc3MiXSwibmJmIjoxNTg3MDI5NDkwLCJleHAiOjE1ODc2MzQyOTAsImlhdCI6MTU4NzAyOTQ5MH0.WJNv3k2vUZNOg6Wvjhg56et2KyX9aJ2Np4l83okK0lU this throw me this error: TypeError: Failed to execute 'fetch' on 'Window': Invalid name   -  person Davecz    schedule 16.04.2020
comment
понятия не имею, что означает ошибка, но в вашем заголовке есть ошибка: слово «Носитель» должно быть после «:», а не перед!   -  person jps    schedule 16.04.2020
comment
Хорошо... это помогает... есть ли способ избежать наличия "носителя" там?   -  person Davecz    schedule 16.04.2020


Ответы (1)


Вам нужно добавить слово Bearer в заголовок Authorization:

Authorization: Bearer eyJhbGciOi..

Тогда это должно работать.


В ответ

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

вы видите не только статус, в данном случае 401, но и заголовок ответа

www-authenticate: Bearer 

который, согласно RFC1945, говорит вам, какую схему использовать:

Значение поля состоит по крайней мере из одного запроса, указывающего схему (схемы) аутентификации и параметры, применимые к Request-URI.

Итак, в данном случае это схема Bearer.

Bearer — это стандартная схема для реализации протокола авторизации OAuth2.0. .

См. также этот вопрос/ответ.

person jps    schedule 16.04.2020