diff --git a/src/Infrastructure/Extensions/AuthorizeSetup.cs b/src/Infrastructure/Extensions/AuthorizeSetup.cs index 100b5fa..beb7c1f 100644 --- a/src/Infrastructure/Extensions/AuthorizeSetup.cs +++ b/src/Infrastructure/Extensions/AuthorizeSetup.cs @@ -26,10 +26,10 @@ public static class AuthorizeSetup var securityKey = new SymmetricSecurityKey(buffer); var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); - services.AddSingleton(new PermissionOptions(ClaimTypes.Role, + services.AddSingleton(new PermissionOptions( audienceOptions.Issuer, audienceOptions.Audience, - TimeSpan.FromSeconds(audienceOptions.Expiration), + audienceOptions.Expiration, signingCredentials)); services.AddAuthorizationBuilder() diff --git a/src/Infrastructure/Security/ITokenBuilder.cs b/src/Infrastructure/Security/ITokenBuilder.cs index 8711f51..790343e 100644 --- a/src/Infrastructure/Security/ITokenBuilder.cs +++ b/src/Infrastructure/Security/ITokenBuilder.cs @@ -1,8 +1,11 @@ -using System.Security.Claims; +using System.Globalization; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; using Infrastructure.Utils; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Extensions.DependencyInjection; -using Microsoft.IdentityModel.JsonWebTokens; +using Microsoft.IdentityModel.Tokens; +using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames; namespace Infrastructure.Security; @@ -11,9 +14,15 @@ public interface ITokenBuilder IList GetClaimsByUserContext(IUserContext userContext); void SetUserContext(TokenValidatedContext context); + + TokenInfo GenerateJwtTokenInfo(IReadOnlyCollection claims); } -public class TokenBuilder : ITokenBuilder +public class TokenBuilder( + PermissionOptions permissionOptions, + JwtSecurityTokenHandler jwtSecurityTokenHandler, + IEncryptionService encryptionService) + : ITokenBuilder { public IList GetClaimsByUserContext(IUserContext userContext) { @@ -23,6 +32,10 @@ public class TokenBuilder : ITokenBuilder new(JwtRegisteredClaimNames.NameId, userContext.Id.ToString()), new(JwtRegisteredClaimNames.Name, userContext.Name), new(JwtRegisteredClaimNames.Email, userContext.Email), + new(JwtRegisteredClaimNames.Iat, + EpochTime.GetIntDate(DateTime.Now).ToString(CultureInfo.InvariantCulture), + ClaimValueTypes.Integer64), + new(JwtRegisteredClaimNames.Exp, permissionOptions.Expiration.ToString()) }; claims.AddRange(userContext.RoleIds.Select(rId => new Claim(ClaimTypes.Role, rId))); return claims; @@ -42,4 +55,18 @@ public class TokenBuilder : ITokenBuilder userContext.RoleIds = principal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray(); userContext.RemoteIpAddress = context.HttpContext.GetRequestIp(); } + + public TokenInfo GenerateJwtTokenInfo(IReadOnlyCollection claims) + { + var jwtToken = new JwtSecurityToken( + issuer: permissionOptions.Issuer, + audience: permissionOptions.Audience, + claims: claims, + notBefore: DateTime.Now, + expires: DateTime.Now.AddSeconds(permissionOptions.Expiration), + signingCredentials: permissionOptions.SigningCredentials); + var token = jwtSecurityTokenHandler.WriteToken(jwtToken); + return new TokenInfo(encryptionService.Encrypt(token), permissionOptions.Expiration, + JwtBearerDefaults.AuthenticationScheme); + } } \ No newline at end of file diff --git a/src/Infrastructure/Security/PermissionOptions.cs b/src/Infrastructure/Security/PermissionOptions.cs index 720a237..f2ca1a9 100644 --- a/src/Infrastructure/Security/PermissionOptions.cs +++ b/src/Infrastructure/Security/PermissionOptions.cs @@ -3,19 +3,16 @@ using Microsoft.IdentityModel.Tokens; namespace Infrastructure.Security; public class PermissionOptions( - string claimType, string issuer, string audience, - TimeSpan expiration, + long expiration, SigningCredentials credentials) { - public string ClaimType { get; } = claimType; - public string Issuer { get; } = issuer; public string Audience { get; } = audience; - public TimeSpan Expiration { get; } = expiration; + public long Expiration { get; } = expiration; public SigningCredentials SigningCredentials { get; } = credentials; } \ No newline at end of file