optimise user context

master
Young 7 months ago
parent 09c84a7c5c
commit 95aba3d268

@ -0,0 +1,8 @@
namespace Infrastructure.HttpUserContext;
public static class ClaimConstants
{
public const string RoleId = "role_id";
public const string PermissionCode = "permission_code";
}

@ -1,4 +1,5 @@
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication.JwtBearer;
namespace Infrastructure.HttpUserContext;
@ -6,50 +7,62 @@ namespace Infrastructure.HttpUserContext;
/// 用户上下文
/// </summary>
/// <typeparam name="TId"></typeparam>
public interface IUserContext<out TId> where TId : IEquatable<TId>
public interface IUserContext<TId> where TId : IEquatable<TId>
{
/// <summary>
/// 用户primary key的类型
/// </summary>
TId Id { get; }
TId Id { get; set; }
/// <summary>
/// 用户名
/// </summary>
string Username { get; }
string Username { get; set; }
/// <summary>
/// 名称
/// </summary>
string Name { get; }
string Name { get; set; }
/// <summary>
/// 邮箱
/// </summary>
string Email { get; }
string Email { get; set; }
/// <summary>
/// 角色id
/// </summary>
string[] RoleIds { get; }
string[] RoleIds { get; set; }
/// <summary>
/// 角色名称
/// </summary>
string[] RoleNames { get; set; }
/// <summary>
/// 权限
/// </summary>
string[] Permissions { get; set; }
/// <summary>
/// 访问Ip
/// </summary>
string RemoteIpAddress { get; }
string RemoteIpAddress { get; set; }
/// <summary>
/// 生成Jwt token信息
/// </summary>
/// <param name="jwtSecurityToken"></param>
/// <param name="claims"></param>
/// <param name="duration"></param>
/// <param name="schemeName"></param>
/// <returns></returns>
JwtTokenInfo GenerateTokenInfo(JwtSecurityToken jwtSecurityToken, double? duration, string schemeName);
JwtTokenInfo GenerateTokenInfo(IList<Claim>? claims = null,
double? duration = null,
string schemeName = JwtBearerDefaults.AuthenticationScheme);
/// <summary>
/// 从当前用户上下文获取claims
/// </summary>
/// <returns></returns>
IList<Claim> GetClaimsFromUserContext();
IList<Claim>? GetClaimsFromUserContext(bool includePermissions = false);
}

@ -24,25 +24,84 @@ public class UserContext<TId>(
{
private readonly ClaimsPrincipal principal = httpContextAccessor?.HttpContext?.User;
public TId Id => GetIdFromClaims();
private TId? _id;
public string Username => principal.Claims.First(c => c.Type == JwtRegisteredClaimNames.UniqueName).Value;
private string? _username;
public string Name => principal.Claims.First(c => c.Type == JwtRegisteredClaimNames.Name).Value;
private string? _name;
public string Email => principal.Claims.First(c => c.Type == JwtRegisteredClaimNames.Email).Value;
private string? _email;
public string[] RoleIds => principal.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray();
private string[]? _roleIds;
public string RemoteIpAddress => httpContextAccessor.HttpContext?.GetRequestIp()!;
private string? _remoteIpAddress;
private string[]? _roleNames;
private string[]? _permissions;
public TId Id
{
get => _id ??= GetIdFromClaims();
set => _id = value;
}
public string Username
{
get => _username ??= principal.Claims.First(c => c.Type == JwtRegisteredClaimNames.UniqueName).Value;
set => _username = value;
}
public string Name
{
get => _name ??= principal.Claims.First(c => c.Type == JwtRegisteredClaimNames.Name).Value;
set => _name = value;
}
public string Email
{
get => _email ??= principal.Claims.First(c => c.Type == JwtRegisteredClaimNames.Email).Value;
set => _email = value;
}
public string[] RoleIds
{
get => _roleIds ??= principal.Claims.Where(c => c.Type == ClaimConstants.RoleId).Select(c => c.Value).ToArray();
set => _roleIds = value;
}
public string[] RoleNames
{
get => _roleNames ??= principal.Claims.Where(c => c.Type == ClaimTypes.Role)
.Select(c => c.Value).ToArray();
set => _roleNames = value;
}
public string[] Permissions
{
get => _permissions ??= principal.Claims.Where(c => c.Type == ClaimConstants.PermissionCode)
.Select(c => c.Value).ToArray();
set => _permissions = value;
}
public string RemoteIpAddress
{
get => _remoteIpAddress ??= httpContextAccessor.HttpContext?.GetRequestIp()!;
set => _remoteIpAddress = value;
}
public JwtTokenInfo GenerateTokenInfo(
JwtSecurityToken? securityToken = null,
IList<Claim>? claims = null,
double? duration = null,
string schemeName = JwtBearerDefaults.AuthenticationScheme)
{
var claims = GetClaimsFromUserContext();
securityToken ??= new JwtSecurityToken(
claims ??= GetClaimsFromUserContext();
if (double.NaN == duration)
{
duration = jwtContext.Duration;
}
var securityToken = new JwtSecurityToken(
issuer: jwtContext.Issuer,
audience: jwtContext.Audience,
claims: claims,
@ -51,10 +110,10 @@ public class UserContext<TId>(
signingCredentials: jwtContext.SigningCredentials);
var token = jwtSecurityTokenHandler.WriteToken(securityToken);
token = encryptionService.Encrypt(token);
return new JwtTokenInfo(token, duration ?? jwtContext.Duration, schemeName);
return new JwtTokenInfo(token, duration.Value, schemeName);
}
public IList<Claim> GetClaimsFromUserContext()
public IList<Claim>? GetClaimsFromUserContext(bool includePermissions = false)
{
var claims = new List<Claim>()
{
@ -68,7 +127,13 @@ public class UserContext<TId>(
new(JwtRegisteredClaimNames.Exp,
TimeSpan.FromSeconds(jwtContext.Duration).ToString())
};
claims.AddRange(RoleIds.Select(rId => new Claim(ClaimTypes.Role, rId)));
claims.AddRange(RoleIds.Select(rId => new Claim(ClaimConstants.RoleId, rId)));
claims.AddRange(RoleNames.Select(rName => new Claim(ClaimTypes.Role, rName)));
if (includePermissions)
{
claims.AddRange(Permissions.Select(p => new Claim(ClaimConstants.PermissionCode, p)));
}
return claims;
}

Loading…
Cancel
Save