summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHombreLaser <sebastian-440@live.com>2022-11-20 19:38:18 -0600
committerHombreLaser <sebastian-440@live.com>2022-11-20 19:38:18 -0600
commite587ec71da3f457a945c1d3c5d6cf8c89445cd11 (patch)
tree12ffa068fb158b4b008b3093b7c008ad49d84aad
parent4d34da521dd05b16b25d1aa2de2567de9d920512 (diff)
Añadido método refresh a controlador de sesiones
-rw-r--r--Controllers/UserAccountSessionsController.cs18
-rw-r--r--Errors/ExpiredSessionError.cs7
-rw-r--r--Logics/BaseUserAccountLogic.cs3
-rw-r--r--Logics/CreateUserAccountLogic.cs1
-rw-r--r--Logics/CreateUserAccountSessionLogic.cs1
-rw-r--r--Logics/RefreshTokenLogic.cs40
-rw-r--r--Models/Raffle.cs2
-rw-r--r--Services/ITokenGenerator.cs2
-rw-r--r--Services/TokenGenerator.cs21
9 files changed, 91 insertions, 4 deletions
diff --git a/Controllers/UserAccountSessionsController.cs b/Controllers/UserAccountSessionsController.cs
index 1309c8e..217c05c 100644
--- a/Controllers/UserAccountSessionsController.cs
+++ b/Controllers/UserAccountSessionsController.cs
@@ -1,5 +1,5 @@
-using AutoMapper;
using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using BackendPIA.Forms;
using BackendPIA.Models;
@@ -11,12 +11,14 @@ namespace BackendPIA.Controllers {
[Route("api/")]
[ApiController]
public class AdministratorSessionsController : ControllerBase {
+ private readonly ApplicationDbContext _context;
private readonly ITokenGenerator _token_generator;
private readonly UserManager<UserAccount> _manager;
- public AdministratorSessionsController(ITokenGenerator token_generator, UserManager<UserAccount> manager) {
+ public AdministratorSessionsController(ITokenGenerator token_generator, UserManager<UserAccount> manager, ApplicationDbContext context) {
_token_generator = token_generator;
_manager = manager;
+ _context = context;
}
[HttpPost("login")]
@@ -29,5 +31,17 @@ namespace BackendPIA.Controllers {
return StatusCode(401, new InvalidLoginError(401, "Check your credentials"));
}
+
+ // [Authorize]
+ [HttpPost("refresh")]
+ public async Task<ActionResult<AuthenticationToken>> Refresh(AuthenticationToken form) {
+ RefreshTokenLogic logic = new RefreshTokenLogic(_token_generator, _manager, form);
+ var result = await logic.Call();
+
+ if(result)
+ return Ok(logic.Token);
+
+ return StatusCode(403, new ExpiredSessionError(401, "Check your refresh token"));
+ }
}
} \ No newline at end of file
diff --git a/Errors/ExpiredSessionError.cs b/Errors/ExpiredSessionError.cs
new file mode 100644
index 0000000..761bbec
--- /dev/null
+++ b/Errors/ExpiredSessionError.cs
@@ -0,0 +1,7 @@
+namespace BackendPIA.Errors {
+ public class ExpiredSessionError : ErrorBase {
+ public int Status { get { return base.Status; } }
+ public string Message { get { return base.Message; }}
+ public ExpiredSessionError(int status, string message) : base(status, message) {}
+ }
+} \ No newline at end of file
diff --git a/Logics/BaseUserAccountLogic.cs b/Logics/BaseUserAccountLogic.cs
index 82c28eb..4ce17e0 100644
--- a/Logics/BaseUserAccountLogic.cs
+++ b/Logics/BaseUserAccountLogic.cs
@@ -19,11 +19,10 @@ namespace BackendPIA.Logics {
var roles = await _manager.GetRolesAsync(user);
_token = new AuthenticationToken { Token = _token_generator.Generate(user, roles[0]),
RefreshToken = _token_generator.GenerateRefreshToken() };
- await SetUserRefreshToken(user);
}
// We overwrite or set the value of the session token in the database: all other previous logins are invalid.
- private async Task SetUserRefreshToken(UserAccount user) {
+ protected async Task SetUserRefreshToken(UserAccount user) {
user.SessionToken = _token.RefreshToken;
user.SessionTokenExpiryTime = DateTime.UtcNow.AddHours(3);
await _manager.UpdateAsync(user);
diff --git a/Logics/CreateUserAccountLogic.cs b/Logics/CreateUserAccountLogic.cs
index dd37837..93859a4 100644
--- a/Logics/CreateUserAccountLogic.cs
+++ b/Logics/CreateUserAccountLogic.cs
@@ -28,6 +28,7 @@ namespace BackendPIA.Logics{
if(result.Succeeded) {
await SetAuthenticationToken(user);
+ await SetUserRefreshToken(user);
return true;
}
diff --git a/Logics/CreateUserAccountSessionLogic.cs b/Logics/CreateUserAccountSessionLogic.cs
index 2e51791..d5c3aeb 100644
--- a/Logics/CreateUserAccountSessionLogic.cs
+++ b/Logics/CreateUserAccountSessionLogic.cs
@@ -21,6 +21,7 @@ namespace BackendPIA.Logics {
if(result) {
await SetAuthenticationToken(user);
+ await SetUserRefreshToken(user);
return true;
}
diff --git a/Logics/RefreshTokenLogic.cs b/Logics/RefreshTokenLogic.cs
new file mode 100644
index 0000000..200438a
--- /dev/null
+++ b/Logics/RefreshTokenLogic.cs
@@ -0,0 +1,40 @@
+using Microsoft.AspNetCore.Identity;
+using BackendPIA.Services;
+using BackendPIA.Models;
+using BackendPIA.Forms;
+
+namespace BackendPIA.Logics {
+ public class RefreshTokenLogic : BaseUserAccountLogic {
+ private readonly AuthenticationToken _form;
+
+ public RefreshTokenLogic(ITokenGenerator token_generator, UserManager<UserAccount> manager, AuthenticationToken form) : base(token_generator, manager) {
+ _form = form;
+ }
+
+ public async Task<bool> Call() {
+ var email = _token_generator.GetPrincipalFromToken(_form.Token);
+
+ if(email == null)
+ return false;
+ // Checks.
+ var user = await _manager.FindByEmailAsync(email);
+
+ if(user == null)
+ return false;
+
+ if(user.SessionTokenExpiryTime == null || user.SessionTokenExpiryTime < DateTime.UtcNow
+ || user.SessionToken == null || user.SessionToken != _form.RefreshToken) {
+ user.SessionToken = null;
+ user.SessionTokenExpiryTime = null;
+ _manager.UpdateAsync(user);
+
+ return false;
+ }
+
+ await SetAuthenticationToken(user);
+ _token.RefreshToken = user.SessionToken;
+
+ return true;
+ }
+ }
+} \ No newline at end of file
diff --git a/Models/Raffle.cs b/Models/Raffle.cs
new file mode 100644
index 0000000..e06b173
--- /dev/null
+++ b/Models/Raffle.cs
@@ -0,0 +1,2 @@
+using System.ComponentModel.DataAnnotations;
+using Microsoft.AspNetCore.Identity; \ No newline at end of file
diff --git a/Services/ITokenGenerator.cs b/Services/ITokenGenerator.cs
index 3738f81..32db2b6 100644
--- a/Services/ITokenGenerator.cs
+++ b/Services/ITokenGenerator.cs
@@ -1,8 +1,10 @@
+using System.Security.Claims;
using BackendPIA.Models;
namespace BackendPIA.Services {
public interface ITokenGenerator {
public string Generate(UserAccount user, string role);
public string GenerateRefreshToken();
+ public string? GetPrincipalFromToken(string token);
}
} \ No newline at end of file
diff --git a/Services/TokenGenerator.cs b/Services/TokenGenerator.cs
index 514417d..f792cf9 100644
--- a/Services/TokenGenerator.cs
+++ b/Services/TokenGenerator.cs
@@ -36,5 +36,26 @@ namespace BackendPIA.Services {
return Convert.ToBase64String(random_number);
}
+
+ public string? GetPrincipalFromToken(string token) {
+ var tokenValidationParameters = new TokenValidationParameters {
+ ValidateAudience = false,
+ ValidateIssuer = false,
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_key)),
+ ValidateLifetime = false
+ };
+ var tokenHandler = new JwtSecurityTokenHandler();
+ SecurityToken security_token;
+ var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out security_token);
+ var jwtSecurityToken = security_token as JwtSecurityToken;
+
+ if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
+ return null;
+
+ var jwt = tokenHandler.ReadJwtToken(token);
+
+ return jwt.Claims.Where(c => c.Type == "email").First().Value;
+ }
}
} \ No newline at end of file