c#asp.net核心承载错误=“ invalid_token” [英] c# asp.net core Bearer error="invalid_token"

查看:651
本文介绍了c#asp.net核心承载错误=“ invalid_token”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以帮我解决这个问题吗?我正在使用邮递员测试API



我正在关注有关asp.net核心的教程。



而且我现在处于身份验证部分。



我不太了解错误的原因。



在本教程中,它具有登录名并返回令牌。



这是登录代码。哪个在工作我知道这是有效的,因为它返回令牌。我也尝试使用无效的登录名。并返回 401未经授权,但是当我使用数据库中找到的正确登录凭据时。它返回令牌

  [HttpPost( login)] 
公共异步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 =新的SecurityTokenDescriptor
{
主题=新的ClaimsIdentity(claims),
Expires = DateTime.Now.AddDays(1),
SigningCredentials =信誉
};

var tokenHandler = new JwtSecurityTokenHandler();

var令牌= 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] 值控制器

  [授权] 
[Route( api / [controller])]
[ApiController]
公共类ValuesController:ControllerBase

这是邮递员的屏幕截图





我遵循了本教程。我粘贴从登录中收到的令牌。但这给了我错误

  WWW-Authenticate→Bearer error = invalid_token,error_description =观众无效 

为什么错误会给我无效令牌令牌来自登录名?我该如何解决?我已经搜索了一段时间,但我无法解决这个问题。谢谢。






更新:



错误是因为我忘了这个

  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
};
});


解决方案

我最近使用了有效的JWT令牌进行了类似的操作邮递员很好。我创建JWT令牌的方法几乎没有什么不同,在您的情况下,问题可能是由于未指定 发行人受众。 p>

您可以尝试以下操作吗?

  var Claims = new List< Claim> ; 
{
新Claim(ClaimTypes.WindowsAccountName,this.User.Identity.Name)
};
Claim userIdClaim = new Claim( UserId, 12345);
Claims.Add(userIdClaim);
//避免重放攻击
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 []角色= Role1,Role2,Role23 .Split(,);

foreach(角色中的字符串角色)
{
Claims.Add(new Claim(role,)));
}

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

var encryptioningCreds =新的EncryptingCredentials(key1,SecurityAlgorithms.Aes128KW,SecurityAlgorithms.Aes128CbcHmacSha256);
var handler = new JwtSecurityTokenHandler();
var t = handler.CreateJwtSecurityToken();
var令牌= handler.CreateJwtSecurityToken( http:// localhost:61768 /, http:// localhost:61768 /
,新ClaimsIdentity(claims)
,到期时间:DateTime .Now.AddMinutes(1)
,signingCredentials:creds
,encryptioningCredentials:encryptingCreds
,notBefore:DateTime.Now
,issueAt:DateTime.Now);
返回新的JwtSecurityTokenHandler()。WriteToken(token);

我的 ConfigureServices 看起来像

  services.AddAuthentication()
.AddJwtBearer(options =>
{
options.RequireHttpsMetadata = false;
options.SaveToken = true;
options.TokenValidationParameters =新的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
};
});

注意:适当更改发行者和密钥。


Can someone please help me to solve this problem? I'm testing the API using Postman

I'm following a tutorial about asp.net core.

And I'm on its Authentication part now.

I don't really understand whats the reason for the error.

In the tutorial, it has a login and it returns token.

This is the code for login. Which is working. I know this is working because it returns a token. I also tried using an invalid login. and it returns 401 Unauthorized But when I use the correct login credentials which are found in the database. It returns token

[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)
        });
}

Then the next part of the tutorial is to limit the access. The user should be logged in first in order to view the content.

Below is the code

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
                };
            });

Then enabled

app.UseAuthentication();

I also enabled the [Authorize] in the Values Controller

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

This is the screenshot of postman

I followed the tutorial. I paste the token I received from login. But it gives me the error

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

Why does the error give me invalid token if the token is from the login? How do I fix this? I've been searching for a while but I can't solve this my self. Thank you.


Update:

The error is because I forgot this

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
                };
            });

解决方案

I recently did similar thing using JWT token which is working fine with Postman. My approach for creating the JWT token is little different, In your case the problem can be due to not specifying the issuer and audience.

Can you try like following.

   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);

And my ConfigureServices looks like

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
                 };
             });

Note: Change the issuer and the key appropriately.

这篇关于c#asp.net核心承载错误=“ invalid_token”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆