Sim. Verifiquei e a data de nascimento está sendo incluída. Estava dando uma revisada no código mas ainda não identifiquei o motivo. Na classe TokenService eu até alterei, conforme sugestão, a maneira de criar a claim relacionada ao nome usando o ClaimTypes.
TokenService.cs
namespace UsuariosApi.Services
{
public class TokenService
{
public string GenerateToken(Usuario usuario)
{
Claim[] claims = new Claim[] {
//new Claim("username", usuario.UserName),
new Claim(ClaimTypes.Name, usuario.UserName),
//new Claim("id", usuario.Id),
new Claim(ClaimTypes.DateOfBirth, usuario.DataNascimento.ToString()),
};
var chave = new byte[32];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(chave);
}
var chaveBase64 = Convert.ToBase64String(chave);
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(chaveBase64));
var signingCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken
(
expires: DateTime.Now.AddMinutes(10),
claims: claims,
signingCredentials: signingCredentials
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
}
Token gerado: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoicm9uYWxkbyIsImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2RhdGVvZmJpcnRoIjoiMS8xLzE5NzAgMTI6MDA6MDAgQU0iLCJleHAiOjE2OTI4ODU4ODl9.ilvO3nrFWd_FCNzMg1w6BXy2fiGX5q--Ef2_rel9WGk
IdadeAuthorization.cs
namespace UsuariosApi.Authorization
{
public class IdadeAuthorization : AuthorizationHandler<IdadeMinima>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IdadeMinima requirement)
{
var dataNascimentoClaim = context.User.FindFirst(claim =>
claim.Type == ClaimTypes.DateOfBirth);
if (dataNascimentoClaim is null) return Task.CompletedTask;
var dataNascimento = Convert.ToDateTime(dataNascimentoClaim.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;
}
}
}
AcessoController.cs:
namespace UsuariosApi.Controllers
{
[ApiController]
[Route("[Controller]")]
public class AcessoController : ControllerBase
{
[HttpGet]
[Authorize(Policy = "IdadeMinima")]
public IActionResult Get()
{
return Ok("Acesso permitido!");
}
}
}
Program.cs:
var builder = WebApplication.CreateBuilder(args);
var connString = builder.Configuration.GetConnectionString("UsuarioConnection");
builder.Services.AddDbContext<UsuarioDbContext>(
opts => {
opts.UseMySql(connString,
ServerVersion.AutoDetect(connString));
});
builder.Services
.AddIdentity<Usuario, IdentityRole>()
.AddEntityFrameworkStores<UsuarioDbContext>()
.AddDefaultTokenProviders();
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
builder.Services.AddSingleton<IAuthorizationHandler, IdadeAuthorization>();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var chave = new byte[32];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(chave);
}
var chaveBase64 = Convert.ToBase64String(chave);
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(chaveBase64));
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme =
JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = key,
ValidateAudience = false,
ValidateIssuer = false,
ClockSkew = TimeSpan.Zero
};
});
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("IdadeMinima", policy =>
policy.AddRequirements(new IdadeMinima(18))
);
});
builder.Services.AddScoped<UsuarioService>();
builder.Services.AddScoped<TokenService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();