diff --git a/src/Server/Controllers/AuthenticationController.cs b/src/Server/Controllers/AuthenticationController.cs index 16ce01e..a8d2a3f 100755 --- a/src/Server/Controllers/AuthenticationController.cs +++ b/src/Server/Controllers/AuthenticationController.cs @@ -4,6 +4,10 @@ using Auth.Services.DatabaseService; using Auth.Entities; using Auth.DTO; using System.Web.Http; +using System.IdentityModel.Tokens.Jwt; +using Microsoft.IdentityModel.Tokens; +using System.Text; +using System.Security.Claims; namespace Auth.Controllers { [ApiController] @@ -71,7 +75,7 @@ namespace Auth.Controllers { } } - [Route("authenticate")] + [Route("jwtlogin")] [HttpPost] public async Task Authenticate([FromBody] LoginRequest request) { try { @@ -107,6 +111,27 @@ namespace Auth.Controllers { } } + [Route("jwttryrenew")] + [HttpPost] + public IActionResult Refresh([FromBody] JWTRenewRequest request){ + try { + JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); + ClaimsPrincipal claimsPrincipal = handler.ValidateToken(request.Token, AuthJWT.TokenParameters, out var validatedToken); + JwtSecurityToken jwt = (JwtSecurityToken)validatedToken; + if (jwt != null) { + if (jwt.ValidTo - DateTime.UtcNow < TimeSpan.FromDays(1)) { + var newJwt = AuthJWT.RenewJWTToken(claimsPrincipal); + return Ok(newJwt); + } + return BadRequest("Not ready to renew"); + } + return BadRequest("Malformed Token"); + } + catch (SecurityTokenException ex) { + return Unauthorized($"Token invalid: {ex.Message}"); + } + } + [Route("logout")] [HttpPost] public ActionResult Logout() { diff --git a/src/Server/DTO/AuthenticationDTO.cs b/src/Server/DTO/AuthenticationDTO.cs index 456ffcb..c2eddcb 100644 --- a/src/Server/DTO/AuthenticationDTO.cs +++ b/src/Server/DTO/AuthenticationDTO.cs @@ -6,6 +6,10 @@ namespace Auth.DTO { public bool StayLoggedIn { get; set; } } + public class JWTRenewRequest { + public string Token { get; set; } = ""; + } + public class RegisterRequest { public string Email { get; set; } = ""; public string UserName { get; set; } = ""; diff --git a/src/Server/Program.cs b/src/Server/Program.cs index 17a5156..5050a5d 100755 --- a/src/Server/Program.cs +++ b/src/Server/Program.cs @@ -73,16 +73,7 @@ builder.Services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { - options.TokenValidationParameters = new TokenValidationParameters { - ValidateIssuer = true, - ValidateAudience = true, - ValidateLifetime = true, - ValidateIssuerSigningKey = true, - ValidIssuer = AuthJWT.TokenIssuer, - ValidAudience = AuthJWT.TokenAudience, - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthJWT.TokenSecretKey)), - ClockSkew = TimeSpan.FromMinutes(1) - }; + options.TokenValidationParameters = AuthJWT.TokenParameters; options.Events = new JwtBearerEvents { OnMessageReceived = context => { context.Token = context.Request.Cookies[AuthJWT.TokenName]; diff --git a/src/Server/Services/jwt.cs b/src/Server/Services/jwt.cs index d5a8e31..aaa82e6 100644 --- a/src/Server/Services/jwt.cs +++ b/src/Server/Services/jwt.cs @@ -11,6 +11,16 @@ namespace Auth.Services { public static string TokenIssuer = "https://auth.mistox.com"; public static string TokenSecretKey = ""; public static string TokenName = "mistox_session"; + public static TokenValidationParameters TokenParameters = new TokenValidationParameters { + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = true, + ValidateIssuerSigningKey = true, + ValidIssuer = AuthJWT.TokenIssuer, + ValidAudience = AuthJWT.TokenAudience, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(AuthJWT.TokenSecretKey)), + ClockSkew = TimeSpan.FromMinutes(1) + }; public static string GenereateJWTToken(Account account, bool StayLoggedIn) { var tokenHandler = new JwtSecurityTokenHandler(); @@ -36,6 +46,16 @@ namespace Auth.Services { return tokenHandler.WriteToken(token); } + public static string RenewJWTToken( ClaimsPrincipal principal ) { + return GenereateJWTToken(new Account { + ID = Convert.ToInt32(principal.FindFirst(ClaimTypes.NameIdentifier)!.Value), + UserName = principal.FindFirst(ClaimTypes.Name)!.Value, + Email = principal.FindFirst(ClaimTypes.Email)!.Value, + Role = principal.FindFirst(ClaimTypes.Role)!.Value, + DataServer = principal.FindFirst(ClaimTypes.UserData)!.Value + }, Convert.ToBoolean(principal.FindFirst(ClaimTypes.IsPersistent)!.Value)); + } + public static void SignIn(HttpResponse Response, bool StayLoggedIn, string jwt) { if (StayLoggedIn) { // Stay logged in cookie