refactor: 重构当前用户模块
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Yi.Framework.Core.CurrentUsers.Accessor;
|
||||||
|
|
||||||
|
namespace Yi.Framework.AspNetCore.CurrentUser
|
||||||
|
{
|
||||||
|
public class HttpContextCurrentPrincipalAccessor : ThreadCurrentPrincipalAccessor
|
||||||
|
{
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
|
|
||||||
|
public HttpContextCurrentPrincipalAccessor(IHttpContextAccessor httpContextAccessor)
|
||||||
|
{
|
||||||
|
_httpContextAccessor = httpContextAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override ClaimsPrincipal GetClaimsPrincipal()
|
||||||
|
{
|
||||||
|
return _httpContextAccessor.HttpContext?.User ?? base.GetClaimsPrincipal();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Yi.Framework.Core.Const;
|
|
||||||
using Yi.Framework.Core.CurrentUsers;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
|
||||||
{
|
|
||||||
public static class CurrentUserUseExtensions
|
|
||||||
{
|
|
||||||
public static IApplicationBuilder UseCurrentUserServer(this IApplicationBuilder app)
|
|
||||||
{
|
|
||||||
return app.UseMiddleware<CurrentUserMiddleware>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CurrentUserMiddleware
|
|
||||||
{
|
|
||||||
|
|
||||||
private readonly RequestDelegate _next;
|
|
||||||
private ILogger<CurrentUserMiddleware> _logger;
|
|
||||||
public CurrentUserMiddleware(RequestDelegate next, ILogger<CurrentUserMiddleware> logger)
|
|
||||||
{
|
|
||||||
_next = next;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context, ICurrentUser _currentUser)
|
|
||||||
{
|
|
||||||
var authenticateContext = await context.AuthenticateAsync();
|
|
||||||
if (authenticateContext.Principal is null)
|
|
||||||
{
|
|
||||||
_currentUser.IsAuthenticated = false;
|
|
||||||
await _next(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var claims = authenticateContext.Principal.Claims;
|
|
||||||
//通过鉴权之后,开始赋值
|
|
||||||
_currentUser.IsAuthenticated = true;
|
|
||||||
_currentUser.Id = claims.GetClaim(TokenTypeConst.Id) is null ? 0 : Convert.ToInt64(claims.GetClaim(TokenTypeConst.Id));
|
|
||||||
_currentUser.UserName = claims.GetClaim(TokenTypeConst.UserName) ?? "";
|
|
||||||
_currentUser.Permission = claims.GetClaims(TokenTypeConst.Permission);
|
|
||||||
_currentUser.TenantId = claims.GetClaim(TokenTypeConst.TenantId) is null ? null : Guid.Parse(claims.GetClaim(TokenTypeConst.TenantId)!);
|
|
||||||
await _next(context);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ClaimExtension
|
|
||||||
{
|
|
||||||
public static string? GetClaim(this IEnumerable<Claim> claims, string type)
|
|
||||||
{
|
|
||||||
return claims.Where(c => c.Type == type).Select(c => c.Value).FirstOrDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string[]? GetClaims(this IEnumerable<Claim> claims, string type)
|
|
||||||
{
|
|
||||||
return claims.Where(c => c.Type == type).Select(c => c.Value).ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,8 +9,10 @@ using System.Linq;
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Yi.Framework.AspNetCore.CurrentUser;
|
||||||
using Yi.Framework.Core.Const;
|
using Yi.Framework.Core.Const;
|
||||||
using Yi.Framework.Core.CurrentUsers;
|
using Yi.Framework.Core.CurrentUsers;
|
||||||
|
using Yi.Framework.Core.CurrentUsers.Accessor;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.DependencyInjection
|
namespace Microsoft.Extensions.DependencyInjection
|
||||||
{
|
{
|
||||||
@@ -18,7 +20,8 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
{
|
{
|
||||||
public static IServiceCollection AddCurrentUserServer(this IServiceCollection services)
|
public static IServiceCollection AddCurrentUserServer(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
return services.AddScoped<ICurrentUser, CurrentUser>();
|
services.AddSingleton<ICurrentPrincipalAccessor, HttpContextCurrentPrincipalAccessor>();
|
||||||
|
return services.AddTransient<ICurrentUser, CurrentUser>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Yi.Framework.AspNetCore.CurrentUser;
|
||||||
|
using Yi.Framework.Core.CurrentUsers.Accessor;
|
||||||
|
using Yi.Framework.Core.CurrentUsers;
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore
|
namespace Yi.Framework.AspNetCore
|
||||||
{
|
{
|
||||||
@@ -15,12 +18,13 @@ namespace Yi.Framework.AspNetCore
|
|||||||
|
|
||||||
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
|
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
|
||||||
{
|
{
|
||||||
app.UseCurrentUserServer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
|
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
|
||||||
{
|
{
|
||||||
|
services.AddHttpContextAccessor();
|
||||||
services.AddCurrentUserServer();
|
services.AddCurrentUserServer();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Security.Claims;
|
||||||
|
using Yi.Framework.Core.Utils;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Core.CurrentUsers.Accessor
|
||||||
|
{
|
||||||
|
public abstract class CurrentPrincipalAccessorBase : ICurrentPrincipalAccessor
|
||||||
|
{
|
||||||
|
public ClaimsPrincipal Principal => _currentPrincipal.Value ?? GetClaimsPrincipal();
|
||||||
|
|
||||||
|
private readonly AsyncLocal<ClaimsPrincipal> _currentPrincipal = new AsyncLocal<ClaimsPrincipal>();
|
||||||
|
|
||||||
|
protected abstract ClaimsPrincipal GetClaimsPrincipal();
|
||||||
|
|
||||||
|
public virtual IDisposable Change(ClaimsPrincipal principal)
|
||||||
|
{
|
||||||
|
return SetCurrent(principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IDisposable SetCurrent(ClaimsPrincipal principal)
|
||||||
|
{
|
||||||
|
var parent = Principal;
|
||||||
|
_currentPrincipal.Value = principal;
|
||||||
|
return new DisposeAction<ValueTuple<AsyncLocal<ClaimsPrincipal>, ClaimsPrincipal>>(static (state) =>
|
||||||
|
{
|
||||||
|
var (currentPrincipal, parent) = state;
|
||||||
|
currentPrincipal.Value = parent;
|
||||||
|
}, (_currentPrincipal, parent));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Core.CurrentUsers.Accessor
|
||||||
|
{
|
||||||
|
public interface ICurrentPrincipalAccessor
|
||||||
|
{
|
||||||
|
ClaimsPrincipal Principal { get; }
|
||||||
|
IDisposable Change(ClaimsPrincipal principal);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
using Yi.Framework.Core.CurrentUsers.Accessor;
|
||||||
|
|
||||||
|
namespace SF.CurrentUser.CS.Accessor
|
||||||
|
{
|
||||||
|
public class StaticPrincipalAccessor : CurrentPrincipalAccessorBase
|
||||||
|
{
|
||||||
|
public static ClaimsPrincipal ClaimsPrincipal { get; set; }
|
||||||
|
protected override ClaimsPrincipal GetClaimsPrincipal()
|
||||||
|
{
|
||||||
|
return ClaimsPrincipal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Core.CurrentUsers.Accessor
|
||||||
|
{
|
||||||
|
public class ThreadCurrentPrincipalAccessor : CurrentPrincipalAccessorBase
|
||||||
|
{
|
||||||
|
protected override ClaimsPrincipal GetClaimsPrincipal()
|
||||||
|
{
|
||||||
|
return Thread.CurrentPrincipal as ClaimsPrincipal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,31 +1,79 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Yi.Framework.Core.Const;
|
||||||
|
using Yi.Framework.Core.CurrentUsers.Accessor;
|
||||||
|
|
||||||
namespace Yi.Framework.Core.CurrentUsers
|
namespace Yi.Framework.Core.CurrentUsers
|
||||||
{
|
{
|
||||||
public class CurrentUser : ICurrentUser
|
public class CurrentUser : ICurrentUser
|
||||||
{
|
{
|
||||||
public bool IsAuthenticated { get; set; }
|
private readonly ICurrentPrincipalAccessor _principalAccessor;
|
||||||
|
public CurrentUser(ICurrentPrincipalAccessor principalAccessor)
|
||||||
|
{
|
||||||
|
_principalAccessor = principalAccessor;
|
||||||
|
}
|
||||||
|
public bool IsAuthenticated => Id != 0;
|
||||||
|
|
||||||
public long Id { get; set; }
|
public long Id => FindUserId();
|
||||||
|
|
||||||
public string UserName { get; set; } = string.Empty;
|
public string UserName => this.FindClaimValue(TokenTypeConst.UserName);
|
||||||
|
|
||||||
public Guid? TenantId { get; set; }
|
/// <summary>
|
||||||
|
/// 暂时为默认值
|
||||||
|
/// </summary>
|
||||||
|
public Guid TenantId { get; set; } = Guid.Empty;
|
||||||
|
|
||||||
public string Email { get; set; } = string.Empty;
|
public string Email => FindClaimValue(TokenTypeConst.Email);
|
||||||
|
|
||||||
public bool EmailVerified { get; set; }
|
public bool EmailVerified=> false;
|
||||||
|
|
||||||
public string PhoneNumber { get; set; } = string.Empty;
|
public string PhoneNumber => FindClaimValue(TokenTypeConst.PhoneNumber);
|
||||||
|
|
||||||
public bool PhoneNumberVerified { get; set; }
|
public bool PhoneNumberVerified => false;
|
||||||
|
|
||||||
public string[]? Roles { get; set; }
|
public string[]? Roles => this.FindClaims(TokenTypeConst.Roles).Select(c => c.Value).Distinct().ToArray();
|
||||||
|
|
||||||
public string[]? Permission { get; set; }
|
public string[]? Permission => this.FindClaims(TokenTypeConst.Permission).Select(c => c.Value).Distinct().ToArray();
|
||||||
|
|
||||||
|
public virtual Claim FindClaim(string claimType)
|
||||||
|
{
|
||||||
|
return _principalAccessor.Principal?.Claims.FirstOrDefault(c => c.Type == claimType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Claim[] FindClaims(string claimType)
|
||||||
|
{
|
||||||
|
return _principalAccessor.Principal?.Claims.Where(c => c.Type == claimType).ToArray() ?? new Claim[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Claim[] GetAllClaims()
|
||||||
|
{
|
||||||
|
return _principalAccessor.Principal?.Claims.ToArray() ?? new Claim[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FindClaimValue(string claimType)
|
||||||
|
{
|
||||||
|
return FindClaim(claimType)?.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long FindUserId()
|
||||||
|
{
|
||||||
|
var userIdOrNull = _principalAccessor.Principal.Claims?.FirstOrDefault(c => c.Type == TokenTypeConst.Id);
|
||||||
|
if (userIdOrNull == null || string.IsNullOrWhiteSpace(userIdOrNull.Value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (long.TryParse(userIdOrNull.Value, out long userId))
|
||||||
|
{
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,24 +8,24 @@ namespace Yi.Framework.Core.CurrentUsers
|
|||||||
{
|
{
|
||||||
public interface ICurrentUser
|
public interface ICurrentUser
|
||||||
{
|
{
|
||||||
public bool IsAuthenticated { get; set; }
|
public bool IsAuthenticated { get; }
|
||||||
public long Id { get; set; }
|
public long Id { get; }
|
||||||
|
|
||||||
public string UserName { get; set; }
|
public string UserName { get; }
|
||||||
|
|
||||||
public Guid? TenantId { get; set; }
|
public Guid TenantId { get; }
|
||||||
|
|
||||||
public string Email { get; set; }
|
public string Email { get; }
|
||||||
|
|
||||||
public bool EmailVerified { get; set; }
|
public bool EmailVerified { get; }
|
||||||
|
|
||||||
public string PhoneNumber { get; set; }
|
public string PhoneNumber { get; }
|
||||||
|
|
||||||
public bool PhoneNumberVerified { get; set; }
|
public bool PhoneNumberVerified { get; }
|
||||||
|
|
||||||
public string[]? Roles { get; set; }
|
public string[]? Roles { get; }
|
||||||
|
|
||||||
public string[]? Permission { get; set; }
|
public string[]? Permission { get; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Core.Utils
|
||||||
|
{
|
||||||
|
public class DisposeAction<T> : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Action<T> _action;
|
||||||
|
|
||||||
|
private readonly T _parameter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="DisposeAction"/> object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">Action to be executed when this object is disposed.</param>
|
||||||
|
/// <param name="parameter">The parameter of the action.</param>
|
||||||
|
public DisposeAction(Action<T> action, T parameter)
|
||||||
|
{
|
||||||
|
_action = action;
|
||||||
|
_parameter = parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_action(_parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,6 @@ namespace Yi.Framework.Ddd.Repositories
|
|||||||
Task<List<T>> GetPageListAsync(Expression<Func<T, bool>> whereExpression, IPagedAndSortedResultRequestDto page, Expression<Func<T, object>>? orderByExpression = null, OrderByEnum orderByType = OrderByEnum.Asc);
|
Task<List<T>> GetPageListAsync(Expression<Func<T, bool>> whereExpression, IPagedAndSortedResultRequestDto page, Expression<Func<T, object>>? orderByExpression = null, OrderByEnum orderByType = OrderByEnum.Asc);
|
||||||
Task<List<T>> GetPageListAsync(Expression<Func<T, bool>> whereExpression, IPagedAndSortedResultRequestDto page, string? orderBy, OrderByEnum orderByType = OrderByEnum.Asc);
|
Task<List<T>> GetPageListAsync(Expression<Func<T, bool>> whereExpression, IPagedAndSortedResultRequestDto page, string? orderBy, OrderByEnum orderByType = OrderByEnum.Asc);
|
||||||
|
|
||||||
|
|
||||||
//插入
|
//插入
|
||||||
Task<bool> InsertAsync(T insertObj);
|
Task<bool> InsertAsync(T insertObj);
|
||||||
Task<bool> InsertOrUpdateAsync(T data);
|
Task<bool> InsertOrUpdateAsync(T data);
|
||||||
|
|||||||
Reference in New Issue
Block a user