c # asp.net core Ошибка носителя = "invalid_token" - PullRequest
0 голосов
/ 28 января 2019

Может кто-нибудь помочь мне решить эту проблему?Я тестирую API с помощью Postman

Я следую учебному пособию о ядре asp.net.

И я сейчас на его части аутентификации.

Надеюсьдействительно не понимаю, в чем причина ошибки.

В учебном пособии у него есть логин и он возвращает токен.

Это код для входа в систему.Который работает.Я знаю, что это работает, потому что возвращает токен.Я также попытался использовать неверный логин.и он возвращает 401 Unauthorized Но когда я использую правильные учетные данные для входа в систему, которые находятся в базе данных.Возвращает токен

[HttpPost("login")]
public async Task<IActionResult> Login(UserForLoginDto userForLoginDto)
    {
        var userFromRepo = await _repo.Login(userForLoginDto.Username.ToLower(), userForLoginDto.Password);

        if (userFromRepo == null)
            return Unauthorized();

        var claims = new[]
        {
            new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()),
            new Claim(ClaimTypes.Name, userFromRepo.Username)
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config.GetSection("AppSettings:Token").Value));

        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature);

        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = creds
        };

        var tokenHandler = new JwtSecurityTokenHandler();

        var token = tokenHandler.CreateToken(tokenDescriptor);

        return Ok(new {
            token = tokenHandler.WriteToken(token)
        });
}

Затем следующая часть урока ограничивает доступ.Пользователь должен войти в систему в первую очередь для просмотра содержимого.

Ниже приведен код

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>{
                options.TokenValidationParameters = new TokenValidationParameters{
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                    ValidateIssuer = false
                };
            });

Затем включен

app.UseAuthentication();

Я также включил [Authorize] в контроллере значений

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Это скриншот почтальона

enter image description here

Я следовал этому уроку.Я вставляю токен, полученный от логина.Но это дает мне ошибку

WWW-Authenticate →Bearer error="invalid_token", error_description="The audience is invalid"

Почему ошибка дает мне invalid token, если токен от логина?Как это исправить?Я долго искал, но я не могу решить это сам.Спасибо.


Обновление:

Ошибка в том, что я забыл это

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>{
                options.TokenValidationParameters = new TokenValidationParameters{
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
                        .GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Полученная вами ошибка связана с аудиторией, вы должны либо включить ValidAudience, либо установить для ValidateAudience значение false в своих вариантах.

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => {
            options.TokenValidationParameters = new TokenValidationParameters{
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
            ValidateIssuer = false,
            ValidateAudience = false
          };
        });
0 голосов
/ 28 января 2019

Недавно я сделал похожую вещь, используя токен JWT, который отлично работает с Postman.Мой подход к созданию токена JWT немного отличается, В вашем случае проблема может быть в том, что вы не указали эмитента и аудиторию .

Можете ли вы попытаться сделать следующее:

   var claims = new List<Claim>
    {
        new Claim(ClaimTypes.WindowsAccountName, this.User.Identity.Name)
    };
    Claim userIdClaim = new Claim("UserId", "12345");
    claims.Add(userIdClaim);
    //Avoid Replay attack
    claims.Add(new Claim(ClaimTypes.GivenName, "User GivenName"));
    claims.Add(new Claim(ClaimTypes.Surname, "UserSurname"));
    claims.Add(new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()));

    string[] roles = "Role1,Role2,Role23".Split(",");

    foreach (string role in roles)
    {
        claims.Add(new Claim(role, ""));
    }

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("veryVerySecretKey"));
    var key1 = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("ASEFRFDDWSDRGYHF")); 
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var encryptingCreds = new EncryptingCredentials(key1, SecurityAlgorithms.Aes128KW, SecurityAlgorithms.Aes128CbcHmacSha256);
    var handler = new JwtSecurityTokenHandler();
    var t = handler.CreateJwtSecurityToken();
    var token = handler.CreateJwtSecurityToken("http://localhost:61768/", "http://localhost:61768/"
        , new ClaimsIdentity(claims)
        , expires: DateTime.Now.AddMinutes(1)
        , signingCredentials: creds
        , encryptingCredentials :encryptingCreds
        , notBefore:DateTime.Now
        ,  issuedAt:DateTime.Now);
    return new JwtSecurityTokenHandler().WriteToken(token);

А мой ConfigureServices выглядит как

services.AddAuthentication()
            .AddJwtBearer(options =>
             {
                 options.RequireHttpsMetadata = false;
                 options.SaveToken = true;
                 options.TokenValidationParameters = new TokenValidationParameters
                 {
                     ValidateIssuer = true,
                     ValidateAudience = true,
                     ValidateLifetime = true,
                     ValidateIssuerSigningKey = true,
                     ValidIssuer = "http://localhost:61768/",
                     ValidAudience = "http://localhost:61768/",
                     TokenDecryptionKey= new SymmetricSecurityKey(Encoding.UTF8.GetBytes("ASEFRFDDWSDRGYHF")),
                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("veryVerySecretKey")),
                     ClockSkew = TimeSpan.Zero
                 };
             });

Примечание: измените эмитента и ключ соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...