From 3339b01715a8eed0dc0953f95832214c1a1aa049 Mon Sep 17 00:00:00 2001 From: PopeyeZhong <9555843@qq.com> Date: Wed, 13 Mar 2024 15:12:05 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=AE=89=E5=85=A8=E8=BA=AB?= =?UTF-8?q?=E4=BB=BD=E8=BD=AC=E6=8D=A2=E7=9B=B8=E5=85=B3=E7=9A=84=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E5=92=8C=E5=AE=9E=E7=8E=B0=E3=80=82=20:fried=5Fshrimp?= =?UTF-8?q?:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Security/ClaimsIdentityModel.cs | 89 +++++++++++++++++++ .../Security/ClaimsPrincipalTransformer.cs | 5 +- .../Security/Membership/UserIdentityBase.cs | 31 ------- 3 files changed, 90 insertions(+), 35 deletions(-) create mode 100644 Zongsoft.Core/src/Security/ClaimsIdentityModel.cs diff --git a/Zongsoft.Core/src/Security/ClaimsIdentityModel.cs b/Zongsoft.Core/src/Security/ClaimsIdentityModel.cs new file mode 100644 index 00000000..794a9ddd --- /dev/null +++ b/Zongsoft.Core/src/Security/ClaimsIdentityModel.cs @@ -0,0 +1,89 @@ +/* + * _____ ______ + * /_ / ____ ____ ____ _________ / __/ /_ + * / / / __ \/ __ \/ __ \/ ___/ __ \/ /_/ __/ + * / /__/ /_/ / / / / /_/ /\_ \/ /_/ / __/ /_ + * /____/\____/_/ /_/\__ /____/\____/_/ \__/ + * /____/ + * + * Authors: + * 钟峰(Popeye Zhong) + * + * Copyright (C) 2010-2020 Zongsoft Studio + * + * This file is part of Zongsoft.Core library. + * + * The Zongsoft.Core is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, + * or (at your option) any later version. + * + * The Zongsoft.Core is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the Zongsoft.Core library. If not, see . + */ + +using System; +using System.Linq; +using System.Security.Claims; + +namespace Zongsoft.Security +{ + public static class ClaimsIdentityModel + { + #region 私有变量 + private static readonly Caching.MemoryCache _cache = new(); + #endregion + + #region 公共方法 + public static TIdentityModel Get(string scheme = null) where TIdentityModel : class => + GetCore((Services.ApplicationContext.Current?.Principal ?? ClaimsPrincipal.Current) as CredentialPrincipal, scheme); + + public static TIdentityModel Get(string scheme, Func configure) where TIdentityModel : class => + GetCore((Services.ApplicationContext.Current?.Principal ?? ClaimsPrincipal.Current) as CredentialPrincipal, scheme, identity => identity.AsModel(configure)); + + public static TIdentityModel Get(string scheme, IClaimsIdentityTransformer transformer) where TIdentityModel : class => + GetCore((Services.ApplicationContext.Current?.Principal ?? ClaimsPrincipal.Current) as CredentialPrincipal, scheme, identity => transformer.Transform(identity) as TIdentityModel); + + public static TIdentityModel Get(CredentialPrincipal principal, string scheme = null) where TIdentityModel : class => + GetCore(principal, scheme); + + public static TIdentityModel Get(CredentialPrincipal principal, string scheme, Func configure) where TIdentityModel : class => + GetCore(principal, scheme, identity => identity.AsModel(configure)); + + public static TIdentityModel Get(CredentialPrincipal principal, string scheme, IClaimsIdentityTransformer transformer) where TIdentityModel : class => + GetCore(principal, scheme, identity => transformer.Transform(identity) as TIdentityModel); + + private static TIdentityModel GetCore(CredentialPrincipal principal, string scheme, Func transform = null) where TIdentityModel : class + { + if(principal == null || principal.CredentialId == null) + return null; + + //如果指定的安全主体中对应的身份模型已缓存则直接返回 + if(_cache.TryGetValue(GetCacheKey(principal.CredentialId, scheme), out var identityModel) && identityModel != null) + return (TIdentityModel)identityModel; + + //确认当前的安全身份标识 + var identity = principal.GetIdentity(scheme); + + //将当前安全身份标识转换为身份模型 + var model = transform == null ? identity.AsModel() : transform(identity); + + //如果安全主体的有效期大于零则将身份模型缓存起来 + if(principal.Validity > TimeSpan.Zero) + _cache.SetValue(GetCacheKey(principal.CredentialId, scheme), model, principal.Validity.TotalHours > 24 ? TimeSpan.FromHours(24) : principal.Validity); + + return model; + } + #endregion + + #region 私有方法 + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + static string GetCacheKey(string credentialId, string scheme) => string.IsNullOrEmpty(scheme) ? credentialId : $"{credentialId}:{scheme}"; + #endregion + } +} \ No newline at end of file diff --git a/Zongsoft.Core/src/Security/ClaimsPrincipalTransformer.cs b/Zongsoft.Core/src/Security/ClaimsPrincipalTransformer.cs index 24cddf3b..8cede80d 100644 --- a/Zongsoft.Core/src/Security/ClaimsPrincipalTransformer.cs +++ b/Zongsoft.Core/src/Security/ClaimsPrincipalTransformer.cs @@ -34,9 +34,6 @@ using System.Security.Claims; using System.Security.Principal; -using Zongsoft.Security; -using Zongsoft.Security.Membership; - namespace Zongsoft.Security { [DefaultMember(nameof(Transformers))] @@ -113,7 +110,7 @@ protected virtual object OnTransform(ClaimsIdentity identity) return transformer.Transform(identity); } - return identity.AsModel(); + return null; } #endregion } diff --git a/Zongsoft.Core/src/Security/Membership/UserIdentityBase.cs b/Zongsoft.Core/src/Security/Membership/UserIdentityBase.cs index 983107e4..7e65cdd6 100644 --- a/Zongsoft.Core/src/Security/Membership/UserIdentityBase.cs +++ b/Zongsoft.Core/src/Security/Membership/UserIdentityBase.cs @@ -34,10 +34,6 @@ namespace Zongsoft.Security.Membership { public abstract class UserIdentityBase : IUserIdentity, IEquatable { - #region 静态变量 - private static readonly Caching.MemoryCache _cache = new(); - #endregion - #region 构造函数 protected UserIdentityBase() { } #endregion @@ -50,33 +46,6 @@ protected UserIdentityBase() { } public string Description { get; set; } #endregion - #region 静态方法 - protected static TIdentity Get(Func transform) where TIdentity : class, IUserIdentity => Get((Services.ApplicationContext.Current?.Principal ?? ClaimsPrincipal.Current) as CredentialPrincipal, string.Empty, transform); - protected static TIdentity Get(string scheme, Func transform) where TIdentity : class, IUserIdentity => Get((Services.ApplicationContext.Current?.Principal ?? ClaimsPrincipal.Current) as CredentialPrincipal, scheme, transform); - protected static TIdentity Get(CredentialPrincipal principal, Func transform) where TIdentity : class, IUserIdentity => Get(principal, string.Empty, transform); - protected static TIdentity Get(CredentialPrincipal principal, string scheme, Func transform) where TIdentity : class, IUserIdentity - { - if(principal == null || principal.CredentialId == null) - return null; - - //如果指定的安全主体对应的用户身份已缓存则直接返回 - if(_cache.TryGetValue(principal.CredentialId, out var cachedUser) && cachedUser != null) - return (TIdentity)cachedUser; - - //确认当前的安全身份标识 - var identity = principal.GetIdentity(scheme); - - //将当前安全身份标识转换为用户身份 - var user = transform(identity); - - //如果安全主体的有效期大于零则将用户身份缓存起来 - if(principal.Validity > TimeSpan.Zero) - _cache.SetValue(principal.CredentialId, user, principal.Validity.TotalHours > 24 ? TimeSpan.FromHours(24) : principal.Validity); - - return user; - } - #endregion - #region 重写方法 public bool Equals(IUserIdentity user) => user != null && user.UserId == this.UserId; public override bool Equals(object obj) => this.Equals(obj as IUserIdentity);