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 System.Security.Claims;
using Microsoft.AspNetCore.Authentication.JwtBearer;
namespace Infrastructure.HttpUserContext; namespace Infrastructure.HttpUserContext;
@ -6,50 +7,62 @@ namespace Infrastructure.HttpUserContext;
/// 用户上下文 /// 用户上下文
/// </summary> /// </summary>
/// <typeparam name="TId"></typeparam> /// <typeparam name="TId"></typeparam>
public interface IUserContext<out TId> where TId : IEquatable<TId> public interface IUserContext<TId> where TId : IEquatable<TId>
{ {
/// <summary> /// <summary>
/// 用户primary key的类型 /// 用户primary key的类型
/// </summary> /// </summary>
TId Id { get; } TId Id { get; set; }
/// <summary> /// <summary>
/// 用户名 /// 用户名
/// </summary> /// </summary>
string Username { get; } string Username { get; set; }
/// <summary> /// <summary>
/// 名称 /// 名称
/// </summary> /// </summary>
string Name { get; } string Name { get; set; }
/// <summary> /// <summary>
/// 邮箱 /// 邮箱
/// </summary> /// </summary>
string Email { get; } string Email { get; set; }
/// <summary> /// <summary>
/// 角色id /// 角色id
/// </summary> /// </summary>
string[] RoleIds { get; } string[] RoleIds { get; set; }
/// <summary>
/// 角色名称
/// </summary>
string[] RoleNames { get; set; }
/// <summary>
/// 权限
/// </summary>
string[] Permissions { get; set; }
/// <summary> /// <summary>
/// 访问Ip /// 访问Ip
/// </summary> /// </summary>
string RemoteIpAddress { get; } string RemoteIpAddress { get; set; }
/// <summary> /// <summary>
/// 生成Jwt token信息 /// 生成Jwt token信息
/// </summary> /// </summary>
/// <param name="jwtSecurityToken"></param> /// <param name="claims"></param>
/// <param name="duration"></param> /// <param name="duration"></param>
/// <param name="schemeName"></param> /// <param name="schemeName"></param>
/// <returns></returns> /// <returns></returns>
JwtTokenInfo GenerateTokenInfo(JwtSecurityToken jwtSecurityToken, double? duration, string schemeName); JwtTokenInfo GenerateTokenInfo(IList<Claim>? claims = null,
double? duration = null,
string schemeName = JwtBearerDefaults.AuthenticationScheme);
/// <summary> /// <summary>
/// 从当前用户上下文获取claims /// 从当前用户上下文获取claims
/// </summary> /// </summary>
/// <returns></returns> /// <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; 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( public JwtTokenInfo GenerateTokenInfo(
JwtSecurityToken? securityToken = null, IList<Claim>? claims = null,
double? duration = null, double? duration = null,
string schemeName = JwtBearerDefaults.AuthenticationScheme) string schemeName = JwtBearerDefaults.AuthenticationScheme)
{ {
var claims = GetClaimsFromUserContext(); claims ??= GetClaimsFromUserContext();
securityToken ??= new JwtSecurityToken( if (double.NaN == duration)
{
duration = jwtContext.Duration;
}
var securityToken = new JwtSecurityToken(
issuer: jwtContext.Issuer, issuer: jwtContext.Issuer,
audience: jwtContext.Audience, audience: jwtContext.Audience,
claims: claims, claims: claims,
@ -51,10 +110,10 @@ public class UserContext<TId>(
signingCredentials: jwtContext.SigningCredentials); signingCredentials: jwtContext.SigningCredentials);
var token = jwtSecurityTokenHandler.WriteToken(securityToken); var token = jwtSecurityTokenHandler.WriteToken(securityToken);
token = encryptionService.Encrypt(token); 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>() var claims = new List<Claim>()
{ {
@ -68,7 +127,13 @@ public class UserContext<TId>(
new(JwtRegisteredClaimNames.Exp, new(JwtRegisteredClaimNames.Exp,
TimeSpan.FromSeconds(jwtContext.Duration).ToString()) 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; return claims;
} }

Loading…
Cancel
Save