Add project files.
This commit is contained in:
		
							
								
								
									
										146
									
								
								Core.Cerberos.Adapters/Services/TokenService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								Core.Cerberos.Adapters/Services/TokenService.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,146 @@ | ||||
| // *********************************************************************** | ||||
| // <copyright file="T5okenService.cs"> | ||||
| //     Heath | ||||
| // </copyright> | ||||
| // *********************************************************************** | ||||
| using Core.Cerberos.Adapters.Common.Constants; | ||||
| using Core.Cerberos.Adapters.Contracts; | ||||
| using Core.Cerberos.Adapters.Options; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.Options; | ||||
| using Microsoft.IdentityModel.Tokens; | ||||
| using System.Data; | ||||
| using System.IdentityModel.Tokens.Jwt; | ||||
| using System.Security.Claims; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace Core.Cerberos.Adapters.Services | ||||
| { | ||||
|     /// <summary> | ||||
|     /// Service responsible for manage authenticacion. | ||||
|     /// </summary> | ||||
|     public class TokenService : ITokenService | ||||
|     { | ||||
|         private readonly JwtSecurityTokenHandler tokenHandler; | ||||
|         private readonly IConfiguration configuration; | ||||
|         private readonly JwtIssuerOptions jwtOptions; | ||||
|         private readonly JsonSerializerOptions jsonOptions; | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Initializes a new instance of the <see cref="TokenService"/> class. | ||||
|         /// </summary> | ||||
|         public TokenService( | ||||
|             IConfiguration configuration, | ||||
|             IOptions<JwtIssuerOptions> jwtOptions | ||||
|             ) | ||||
|         { | ||||
|             tokenHandler = new JwtSecurityTokenHandler(); | ||||
|             this.configuration = configuration; | ||||
|             this.jwtOptions = jwtOptions.Value; | ||||
|             jsonOptions = new JsonSerializerOptions | ||||
|             { | ||||
|                 PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | ||||
|                 WriteIndented = false | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Refreshes the token. | ||||
|         /// </summary> | ||||
|         public IActionResult RefreshAccessToken(HttpContext httpContext, TokenAdapter tokenAdapter) | ||||
|         { | ||||
|             var tokenString = httpContext.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last(); | ||||
|  | ||||
|             if (tokenString is not null) | ||||
|             { | ||||
|                 var oldToken = tokenHandler.ReadJwtToken(tokenString); | ||||
|  | ||||
|                 var tokenExpiration = oldToken.Claims.FirstOrDefault(c => c.Type == "exp")?.Value; | ||||
|  | ||||
|                 var difference = ValidateTokenExpiration(tokenExpiration ?? ""); | ||||
|  | ||||
|                 if (difference.Value.TotalMinutes <= 5) | ||||
|  | ||||
|                     return new OkObjectResult(GenerateAccessToken(tokenAdapter)); | ||||
|             } | ||||
|  | ||||
|             return new BadRequestObjectResult("The token could not be refreshed"); | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Generates a JWT token for the provided user data. | ||||
|         /// </summary> | ||||
|         /// <param name="user">The user data.</param> | ||||
|         /// <returns>The user DTO with the generated token.</returns> | ||||
|         public string GenerateAccessToken(TokenAdapter adapter) | ||||
|         { | ||||
|  | ||||
|  | ||||
|             var hours = 1; | ||||
|             var minutes = 0; | ||||
|             var expires = DateTime.UtcNow | ||||
|                     .AddHours(hours) | ||||
|                     .AddMinutes(minutes); | ||||
|  | ||||
|             var tokenDescriptor = new SecurityTokenDescriptor | ||||
|             { | ||||
|                 Subject = new ClaimsIdentity(new Claim[] | ||||
|                 { | ||||
|  | ||||
|                     new Claim(Claims.Name, adapter?.User?.DisplayName ?? string.Empty), | ||||
|                     new Claim(Claims.GUID, adapter?.User?.Guid ?? string.Empty), | ||||
|                     new Claim(Claims.Email, adapter?.User?.Email ?? string.Empty), | ||||
|                     new Claim(Claims.Role, adapter?.Role?.Name ?? string.Empty), | ||||
|                     new Claim(Claims.RoleId, adapter?.Role?.Id ?? string.Empty), | ||||
|                     new Claim(Claims.Applications, JsonSerializer.Serialize(adapter?.Role?.Applications), JsonClaimValueTypes.JsonArray), | ||||
|                     new Claim(Claims.Modules, JsonSerializer.Serialize(adapter?.Modules?.Select(m => new { m.Name, m.Application, m.Route, m.Icon, m.Order }), jsonOptions), JsonClaimValueTypes.JsonArray), | ||||
|                     new Claim(Claims.Companies, JsonSerializer.Serialize(adapter?.User?.Companies), JsonClaimValueTypes.JsonArray), | ||||
|                     new Claim(Claims.Projects, JsonSerializer.Serialize(adapter?.User?.Projects), JsonClaimValueTypes.JsonArray), | ||||
|                     new Claim(Claims.Permissions, JsonSerializer.Serialize(adapter?.Permissions?.Select(p => $"{p.Name}.{p.AccessLevel}".Replace(" ", "")).ToArray()), JsonClaimValueTypes.JsonArray), | ||||
|                 }), | ||||
|  | ||||
|                 Expires = expires, | ||||
|                 Issuer = jwtOptions.Issuer, | ||||
|                 Audience = jwtOptions.Audience, | ||||
|                 SigningCredentials = jwtOptions.SigningCredentials | ||||
|             }; | ||||
|  | ||||
|             var token = tokenHandler.CreateEncodedJwt(tokenDescriptor); | ||||
|  | ||||
|             return token; | ||||
|         } | ||||
|  | ||||
|         public ActionResult<TimeSpan> ValidateTokenExpiration(string tokenExpiration) | ||||
|         { | ||||
|             long unixTimestamp = long.Parse(tokenExpiration ?? "0"); | ||||
|             DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(unixTimestamp); | ||||
|             DateTime dateTimeExpiration = dateTimeOffset.UtcDateTime; | ||||
|  | ||||
|             var difference = dateTimeExpiration - DateTime.UtcNow; | ||||
|  | ||||
|             if (difference.TotalMinutes <= 0) | ||||
|  | ||||
|                 return new BadRequestObjectResult("Expired token"); | ||||
|  | ||||
|             else return difference; | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Extracts the user email claim from the http context. | ||||
|         /// </summary> | ||||
|         public string GetEmailClaim(HttpContext httpContext) | ||||
|         { | ||||
|             var tokenHandler = new JwtSecurityTokenHandler(); | ||||
|  | ||||
|             var tokenString = httpContext.Request.Headers.Authorization.FirstOrDefault()?.Split(" ").Last(); | ||||
|             var token = tokenHandler.ReadJwtToken(tokenString); | ||||
|             var email = !string.IsNullOrEmpty(token.Claims.FirstOrDefault(c => c.Type == "email")?.Value) | ||||
|                 ? token.Claims.FirstOrDefault(c => c.Type == "email")?.Value | ||||
|                 : token.Claims.FirstOrDefault(c => c.Type == "preferred_username")?.Value; | ||||
|  | ||||
|             return (email is not null) ? email : ""; | ||||
|         } | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Sergio Matias Urquin
					Sergio Matias Urquin