diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Microsoft/AspNetCore/Authentication/OAuth/Claims/AbpClaimActionCollectionExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Microsoft/AspNetCore/Authentication/OAuth/Claims/AbpClaimActionCollectionExtensions.cs index f51706113a..2ad72955af 100644 --- a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Microsoft/AspNetCore/Authentication/OAuth/Claims/AbpClaimActionCollectionExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Microsoft/AspNetCore/Authentication/OAuth/Claims/AbpClaimActionCollectionExtensions.cs @@ -11,12 +11,14 @@ namespace Microsoft.AspNetCore.Authentication.OAuth.Claims { claimActions.MapJsonKey(AbpClaimTypes.UserName, "name"); claimActions.DeleteClaim("name"); + claimActions.RemoveDuplicate(AbpClaimTypes.UserName); } if (AbpClaimTypes.Email != "email") { claimActions.MapJsonKey(AbpClaimTypes.Email, "email"); claimActions.DeleteClaim("email"); + claimActions.RemoveDuplicate(AbpClaimTypes.Email); } if (AbpClaimTypes.EmailVerified != "email_verified") @@ -38,11 +40,18 @@ namespace Microsoft.AspNetCore.Authentication.OAuth.Claims { claimActions.MapJsonKeyMultiple(AbpClaimTypes.Role, "role"); } + + claimActions.RemoveDuplicate(AbpClaimTypes.Name); } public static void MapJsonKeyMultiple(this ClaimActionCollection claimActions, string claimType, string jsonKey) { claimActions.Add(new MultipleClaimAction(claimType, jsonKey)); } + + public static void RemoveDuplicate(this ClaimActionCollection claimActions, string claimType) + { + claimActions.Add(new RemoveDuplicateClaimAction(claimType)); + } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs index 0c3b05090c..66ca78026d 100644 --- a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/MultipleClaimAction.cs @@ -1,4 +1,5 @@ -using System.Security.Claims; +using System.Linq; +using System.Security.Claims; using System.Text.Json; using Microsoft.AspNetCore.Authentication.OAuth.Claims; @@ -24,15 +25,24 @@ namespace Volo.Abp.AspNetCore.Authentication.OAuth.Claims return; } + Claim claim; switch (prop.ValueKind) { case JsonValueKind.String: - identity.AddClaim(new Claim(ClaimType, prop.GetString(), ValueType, issuer)); + claim = new Claim(ClaimType, prop.GetString(), ValueType, issuer); + if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value)) + { + identity.AddClaim(claim); + } break; case JsonValueKind.Array: foreach (var arramItem in prop.EnumerateArray()) { - identity.AddClaim(new Claim(ClaimType, arramItem.GetString(), ValueType, issuer)); + claim = new Claim(ClaimType, arramItem.GetString(), ValueType, issuer); + if (!identity.Claims.Any(c => c.Type == claim.Type && c.Value == claim.Value)) + { + identity.AddClaim(claim); + } } break; default: diff --git a/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/RemoveDuplicateClaimAction.cs b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/RemoveDuplicateClaimAction.cs new file mode 100644 index 0000000000..ab3e4027c2 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Authentication.OAuth/Volo/Abp/AspNetCore/Authentication/OAuth/Claims/RemoveDuplicateClaimAction.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Text.Json; +using Microsoft.AspNetCore.Authentication.OAuth.Claims; + +namespace Volo.Abp.AspNetCore.Authentication.OAuth.Claims +{ + public class RemoveDuplicateClaimAction : ClaimAction + { + public RemoveDuplicateClaimAction(string claimType) + : base(claimType, ClaimValueTypes.String) + { + } + + /// + public override void Run(JsonElement userData, ClaimsIdentity identity, string issuer) + { + var claims = identity.Claims.Where(c => c.Type == ClaimType).ToArray(); + if (claims.Length < 2) + { + return; + } + + var previousValues = new List(); + foreach (var claim in claims) + { + if (claim.Value.IsIn(previousValues)) + { + identity.RemoveClaim(claim); + } + else + { + previousValues.Add(claim.Value); + } + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs index 25dffced76..87878fc5d6 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Permissions/RolePermissionValueProvider.cs @@ -26,7 +26,7 @@ namespace Volo.Abp.Authorization.Permissions return PermissionGrantResult.Undefined; } - foreach (var role in roles) + foreach (var role in roles.Distinct()) { if (await PermissionStore.IsGrantedAsync(context.Permission.Name, Name, role)) { @@ -50,7 +50,7 @@ namespace Volo.Abp.Authorization.Permissions return result; } - foreach (var role in roles) + foreach (var role in roles.Distinct()) { var multipleResult = await PermissionStore.IsGrantedAsync(permissionNames.ToArray(), Name, role); diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUser.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUser.cs index e769b9ec11..f0cfb4c284 100644 --- a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUser.cs +++ b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUser.cs @@ -31,7 +31,7 @@ namespace Volo.Abp.Users public virtual Guid? TenantId => _principalAccessor.Principal?.FindTenantId(); - public virtual string[] Roles => FindClaims(AbpClaimTypes.Role).Select(c => c.Value).ToArray(); + public virtual string[] Roles => FindClaims(AbpClaimTypes.Role).Select(c => c.Value).Distinct().ToArray(); private readonly ICurrentPrincipalAccessor _principalAccessor;