diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index 11288c21..bf19e391 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -532,7 +532,7 @@ namespace Oqtane.Controllers var secret = HttpContext.GetSiteSettings().GetValue("JwtOptions:Secret", ""); if (!string.IsNullOrEmpty(secret)) { - token = _jwtManager.GenerateToken(user, secret); + token = _jwtManager.GenerateToken(_tenantManager.GetAlias(), user, secret, "", "", 525600); // 1 year } } return token; diff --git a/Oqtane.Server/Infrastructure/Middleware/JwtMiddleware.cs b/Oqtane.Server/Infrastructure/Middleware/JwtMiddleware.cs index 78333a09..cfc93d76 100644 --- a/Oqtane.Server/Infrastructure/Middleware/JwtMiddleware.cs +++ b/Oqtane.Server/Infrastructure/Middleware/JwtMiddleware.cs @@ -32,10 +32,10 @@ namespace Oqtane.Infrastructure var jwtManager = context.RequestServices.GetService(typeof(IJwtManager)) as IJwtManager; var token = context.Request.Headers["Authorization"].First().Split(" ").Last(); - var user = jwtManager.ValidateToken(token, secret); + var user = jwtManager.ValidateToken(token, secret, "", ""); if (user != null) { - // populate principal + // populate principal (reload user roles to ensure most accurate permission assigments) var _userRoles = context.RequestServices.GetService(typeof(IUserRoleRepository)) as IUserRoleRepository; var principal = (ClaimsIdentity)context.User.Identity; UserSecurity.ResetClaimsIdentity(principal); diff --git a/Oqtane.Server/Security/JwtManager.cs b/Oqtane.Server/Security/JwtManager.cs index 5d64bf10..a4a3597e 100644 --- a/Oqtane.Server/Security/JwtManager.cs +++ b/Oqtane.Server/Security/JwtManager.cs @@ -10,27 +10,30 @@ namespace Oqtane.Security { public interface IJwtManager { - string GenerateToken(User user, string secret); - User ValidateToken(string token, string secret); + string GenerateToken(Alias alias, User user, string secret, string issuer, string audience, int lifetime); + User ValidateToken(string token, string secret, string issuer, string audience); } public class JwtManager : IJwtManager { - public string GenerateToken(User user, string secret) + public string GenerateToken(Alias alias, User user, string secret, string issuer, string audience, int lifetime) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(secret); + var identity = UserSecurity.CreateClaimsIdentity(alias, user); var tokenDescriptor = new SecurityTokenDescriptor { - Subject = new ClaimsIdentity(new[] { new Claim("id", user.UserId.ToString()), new Claim("name", user.Username) }), - Expires = DateTime.UtcNow.AddYears(1), + Subject = new ClaimsIdentity(identity), + Issuer = issuer, + Audience = audience, + Expires = DateTime.UtcNow.AddMinutes(lifetime), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } - public User ValidateToken(string token, string secret) + public User ValidateToken(string token, string secret, string issuer, string audience) { if (!string.IsNullOrEmpty(token)) { @@ -40,10 +43,13 @@ namespace Oqtane.Security { tokenHandler.ValidateToken(token, new TokenValidationParameters { - ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), - ValidateIssuer = false, - ValidateAudience = false, + ValidIssuer = issuer, + ValidAudience = audience, + ValidateIssuerSigningKey = true, + ValidateIssuer = (!string.IsNullOrEmpty(issuer)), + ValidateAudience = (!string.IsNullOrEmpty(audience)), + ValidateLifetime = true, ClockSkew = TimeSpan.Zero }, out SecurityToken validatedToken);