【问题标题】:ASP.NET Core 2.1 Jwt Authentication Token not recognisedASP.NET Core 2.1 Jwt 身份验证令牌无法识别
【发布时间】:2019-03-10 14:59:39
【问题描述】:

我正在尝试为我的应用程序实现 Jwt 身份验证,到目前为止,我已经成功生成了令牌,当我对其进行解码时,它看起来还不错。但是,当我使用 Postman 尝试访问仅用于授权的代码区域时,我收到 UnAuthorized 错误。我发现这是因为 Startup.cs 中的设置。

Startup.cs

var key = Encoding.ASCII.GetBytes(Configuration["JwtAuthentication:SecurityKey"]);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(x =>
{
    x.RequireHttpsMetadata = false;
    x.SaveToken = true;
    x.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidIssuer = Configuration["JwtAuthentication:Issuer"],
        ValidateIssuer = true,
        ValidateLifetime = true,
        ValidateAudience = true
    };
});

如果我将 ValidateIssuer 设置为 false,我可以访问 [Authorized] 控制器,否则它将阻止我访问它。此外,ValidateLifeTime 似乎对我不起作用。即使令牌已过期,它也会继续显示结果。

这就是我在另一个类中生成令牌的方式

public class GenerateToken : Controller
{
    private IConfiguration configuration;
    public GenerateToken(IConfiguration configuration)
    {
        this.configuration = configuration;
    }

    public String Generate(GenerateTokenViewModel Input)
    {
        var tokenHandler = new JwtSecurityTokenHandler();
        List<Claim> claims = new List<Claim>();
        claims.Add(new Claim("UserName", Input.User.UserName));
        claims.Add(new Claim("Email", Input.User.Email));
        claims.Add(new Claim("PhoneNumber", Input.User.PhoneNumber));
        claims.Add(new Claim("FirstName", Input.User.FirstName));
        claims.Add(new Claim("LastName", Input.User.LastName));
        claims.Add(new Claim("Id", Input.User.Id));
        foreach (var item in Input.Roles)
        {
            var currentItem = new UserRoleDetailsViewModel
            {
                Id = item.Id,
                Name = item.Name,
                ApplicationId = item.ApplicationId,
                ApplicationName = item.ApplicationName
            };
            var convertedItem = JsonConvert.SerializeObject(currentItem);
            claims.Add(new Claim("Roles", convertedItem));
        }

        var key = Encoding.ASCII.GetBytes(configuration["JwtAuthentication:SecurityKey"]);
        var tokenDescriptor = new SecurityTokenDescriptor
        {
            Subject = new ClaimsIdentity(claims),
            Issuer = configuration["JwtAuthentication:Issuer"],
            Audience = configuration["JwtAuthentication:Audience"],
            IssuedAt = DateTime.UtcNow,
            NotBefore = DateTime.UtcNow,
            Expires = DateTime.UtcNow.AddDays(7),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
        };
        var token = tokenHandler.CreateToken(tokenDescriptor);
        var output = tokenHandler.WriteToken(token);
        return output;
    }
}

我不确定我能做些什么来解决它。或者,是否有为 .net core 2.1 生成和验证 jwt 的指南?

编辑:

添加控制器

[Authorize]
[Route("api/[controller]")]
[ApiController]
public class AccountsController : ControllerBase
{
    private AccountsData accountsData;
    private readonly ILogger<AccountsController> logger;
    private UserRolesData userRolesData;
    private GenerateToken generateToken;
    public AccountsController(ILogger<AccountsController> logger, GenerateToken generateToken, AccountsData accountsData, UserRolesData userRolesData)
    {
        this.accountsData = accountsData;
        this.logger = logger;
        this.userRolesData = userRolesData;
        this.generateToken = generateToken;
    }

    [HttpGet]
    [AllowAnonymous]
    [Route("Item")]
    public ActionResult Item()
    {
        return Ok("test");
    }

    [HttpGet]
    [Route("GetThis")]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { "value1", "value2" };
    }

    [HttpPost]
    [AllowAnonymous]
    [Route("Authenticate")]
    public ActionResult Authenticate([FromBody]AccountsDto Input)
    {
        LoginViewModel lvm = new LoginViewModel
        {
            Email = Input.Email,
            Password = Input.Password
        };
        var user = accountsData.Authenticate(lvm);
        var token = "";
        if(user == null)
        {
            return NotFound(LoggingGlobals.NotFound);
        }
        else
        {
            var roles = userRolesData.GetUserRoles(user.Id);
            GenerateTokenViewModel gtvm = new GenerateTokenViewModel
            {
                User = user,
                Roles = roles
            };
            token = generateToken.Generate(gtvm);
        }
        return Ok(token);
    }

}

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-core


    【解决方案1】:

    我不完全确定是什么导致了您面临的问题。我确实注意到您有ValidateAudience = true,但没有提供ValidAudience

    无论如何,这里有一个有效的演示。您可以在GitHub here 上找到它。这些是最相关的代码 sn-ps。

    Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    
        var key = Encoding.ASCII.GetBytes("this-is-the-secret");
        services
            .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(x =>
            {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters
                {
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuerSigningKey = true,
                    // 
                    ValidIssuer = "my-auth-server",
                    ValidateIssuer = true,
                    // 
                    ValidAudience = "my-resource-server",
                    ValidateAudience = true,
                    //
                    ValidateLifetime = true,
                };
            });
    }
    

    ValuesController.cs

    public class ValuesController : ControllerBase
    {
        [HttpGet("/api/values")]
        [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
        public ActionResult<string> Values()
        {
            return $"You have authorized access";
        }
    
        [HttpGet("/api/jwt")]
        public ActionResult<string> Jwt()
        {
            var key = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("this-is-the-secret"));
            var descriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[] { /* add claims */}),
                Issuer = "my-auth-server",
                Audience = "my-resource-server",
                SigningCredentials =
                    new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature),
                IssuedAt = DateTime.Now,
                NotBefore = DateTime.Now,
                Expires = DateTime.Now.AddDays(1)
            };
    
            var jwtHandler = new JwtSecurityTokenHandler();
            var token = jwtHandler.CreateToken(descriptor);
            return jwtHandler.WriteToken(token);
    
            // alternatively
            // return jwtHandler.CreateEncodedJwt(descriptor);
        }
    }      
    

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 2015-03-21
      • 1970-01-01
      • 2020-08-22
      • 2019-09-06
      • 2021-04-20
      • 2020-09-04
      • 2022-01-06
      • 2019-07-17
      相关资源
      最近更新 更多