1
resposta

dataNascimentoClaim retornando null

Estou com o mesmo problema de um colega do curso: https://cursos.alura.com.br/forum/topico-datanascimentoclaim-null-318809 dataNascimentoClaim está retornando null, pois na hora de decodificar o token o valor da DateOfBirth simplesmente não é decodificado.

public string GenerateToken(Usuario usuario)
{
    Claim[] claims = new Claim[]
    {
        new Claim(ClaimTypes.DateOfBirth, usuario.DataNascimento.ToString()),
        new Claim(ClaimTypes.Name, usuario.UserName ?? throw new Exception("Não foi possivel encontra nome de usuário")),
        new Claim(ClaimTypes.NameIdentifier, usuario.Id)
    };

    var symetricSecurityKey = _config["SymmetricSecurityKey"] ?? throw new Exception("Não foi possível obter SymmetricSecurityKey");
    var chave = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(symetricSecurityKey));

    var signingCredentials = new SigningCredentials(chave, SecurityAlgorithms.HmacSha256);

    var token = new JwtSecurityToken(
            expires: DateTime.Now.AddHours(8),
            claims: claims,
            signingCredentials: signingCredentials
        );

    return new JwtSecurityTokenHandler().WriteToken(token);
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IdadeMinima requirement)
{
    var dataNascimentoCaim = context.User.FindFirst(claim =>
       claim.Type == ClaimTypes.DateOfBirth);

    if (dataNascimentoCaim == null) return Task.CompletedTask;

    var dataNascimento = Convert.ToDateTime(dataNascimentoCaim.Value);

    var idadeUsuario = DateTime.Today.Year - dataNascimento.Year;

    if (dataNascimento > DateTime.Today.AddYears(-idadeUsuario)) idadeUsuario--;

    if (idadeUsuario > requirement.Idade) context.Succeed(requirement);

    return Task.CompletedTask;
# }
    public class CreateUsuarioDTO
    {
        [Required]
        public string? UserName { get; set; }

        [Required]
        public DateTimeOffset DataNascimento { get; set; }

        [Required]
        [DataType(DataType.Password)]
        public string Password { get; set; } = string.Empty;

        [Required]
        [Compare("Password")]
        public string RePassword { get; set; } = string.Empty;
    }

Como estou usando o Postgresql precisei mudar de DateTime para DateTimeOfset. Verificações já jeitas:

  1. O token possui o DateOfBirth: caso queira verificar esse é um token gerado pelo meu projeto "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9kYXRlb2ZiaXJ0aCI6IjA5LzA4LzIwMDAgMDA6MDA6MDAgKzAwOjAwIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZSI6ImhlZmxhaW5uIiwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNS8wNS9pZGVudGl0eS9jbGFpbXMvbmFtZWlkZW50aWZpZXIiOiI0ZjE0OGUyNi0zZjdjLTRhMjctYWNiMS01MDMwMmIxY2NkOGMiLCJleHAiOjE2OTU0NTU0ODR9.ZHnHRpR2kp7iLPuF0UREMOGRFb6wC00WlGhIEdFlNeg"
  2. O valor retornado no toke pode ser convertido para DateTimeOfSet com o método Parse
  3. Usando o debug verifiquei que de fato o Claim DateOfBirth não está retornando: Imagem do debug
1 resposta

Oi, Heflain, como você está?

Acredito que o problema possa estar na forma como você está convertendo a DataNascimento para string na hora de gerar o token. O método ToString() sem parâmetros pode gerar uma string que não é reconhecida como uma data válida na hora de decodificar o token.

Você pode tentar formatar a data de uma maneira mais padrão na hora de gerar o token, por exemplo:

new Claim(ClaimTypes.DateOfBirth, usuario.DataNascimento.ToString("o")),

O formato "o" é o formato de data/hora universal ordenado e deve ser reconhecido corretamente na hora de decodificar o token.

Outro ponto que pode estar causando o problema é a conversão de DateTimeOffset para DateTime. O DateTimeOffset inclui informações de fuso horário que o DateTime não tem. Quando você faz Convert.ToDateTime(dataNascimentoCaim.Value), pode estar perdendo informações de fuso horário que fazem a data ser reconhecida como inválida.

Nesse caso, você pode tentar converter o valor da claim para DateTimeOffset em vez de DateTime e depois calcular a idade do usuário usando a propriedade Year do DateTimeOffset.

Essa é uma possibilidade, mas é importante lembrar que o problema pode estar em outras partes do código.

Caso o problema persista, estamos por aqui. Só avisar!

Abraços.