diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs
index 5d1f6d8414..b1b97c4b91 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/CurrentUserDto.cs
@@ -11,6 +11,10 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
public Guid? TenantId { get; set; }
+ public Guid? ImpersonatorUserId { get; set; }
+
+ public Guid? ImpersonatorTenantId { get; set; }
+
public string UserName { get; set; }
public string Name { get; set; }
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
index eab7d968a9..c60fdeac93 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
@@ -127,6 +127,8 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
IsAuthenticated = _currentUser.IsAuthenticated,
Id = _currentUser.Id,
TenantId = _currentUser.TenantId,
+ ImpersonatorUserId = _currentUser.FindImpersonatorUserId(),
+ ImpersonatorTenantId = _currentUser.FindImpersonatorTenantId(),
UserName = _currentUser.UserName,
SurName = _currentUser.SurName,
Name = _currentUser.Name,
diff --git a/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs b/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs
index cf2169883c..83a587cc25 100644
--- a/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs
+++ b/framework/src/Volo.Abp.Security/System/Security/Principal/AbpClaimsIdentityExtensions.cs
@@ -17,10 +17,12 @@ namespace System.Security.Principal
{
return null;
}
- if (Guid.TryParse(userIdOrNull.Value, out Guid result))
+
+ if (Guid.TryParse(userIdOrNull.Value, out Guid guid))
{
- return result;
+ return guid;
}
+
return null;
}
@@ -36,7 +38,12 @@ namespace System.Security.Principal
return null;
}
- return Guid.Parse(userIdOrNull.Value);
+ if (Guid.TryParse(userIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
}
public static Guid? FindTenantId([NotNull] this ClaimsPrincipal principal)
@@ -49,7 +56,12 @@ namespace System.Security.Principal
return null;
}
- return Guid.Parse(tenantIdOrNull.Value);
+ if (Guid.TryParse(tenantIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
}
public static Guid? FindTenantId([NotNull] this IIdentity identity)
@@ -64,7 +76,12 @@ namespace System.Security.Principal
return null;
}
- return Guid.Parse(tenantIdOrNull.Value);
+ if (Guid.TryParse(tenantIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
}
public static string FindClientId([NotNull] this ClaimsPrincipal principal)
@@ -105,7 +122,12 @@ namespace System.Security.Principal
return null;
}
- return Guid.Parse(editionIdOrNull.Value);
+ if (Guid.TryParse(editionIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
}
public static Guid? FindEditionId([NotNull] this IIdentity identity)
@@ -120,7 +142,88 @@ namespace System.Security.Principal
return null;
}
- return Guid.Parse(editionIdOrNull.Value);
+ if (Guid.TryParse(editionIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
+ }
+
+ public static Guid? FindImpersonatorTenantId([NotNull] this ClaimsPrincipal principal)
+ {
+ Check.NotNull(principal, nameof(principal));
+
+ var impersonatorTenantIdOrNull = principal.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.ImpersonatorTenantId);
+ if (impersonatorTenantIdOrNull == null || impersonatorTenantIdOrNull.Value.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ if (Guid.TryParse(impersonatorTenantIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
+ }
+
+ public static Guid? FindImpersonatorTenantId([NotNull] this IIdentity identity)
+ {
+ Check.NotNull(identity, nameof(identity));
+
+ var claimsIdentity = identity as ClaimsIdentity;
+
+ var impersonatorTenantIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.ImpersonatorTenantId);
+ if (impersonatorTenantIdOrNull == null || impersonatorTenantIdOrNull.Value.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ if (Guid.TryParse(impersonatorTenantIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
+ }
+
+ public static Guid? FindImpersonatorUserId([NotNull] this ClaimsPrincipal principal)
+ {
+ Check.NotNull(principal, nameof(principal));
+
+ var impersonatorUserIdOrNull = principal.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.ImpersonatorUserId);
+ if (impersonatorUserIdOrNull == null || impersonatorUserIdOrNull.Value.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ if (Guid.TryParse(impersonatorUserIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
+ }
+
+ public static Guid? FindImpersonatorUserId([NotNull] this IIdentity identity)
+ {
+ Check.NotNull(identity, nameof(identity));
+
+ var claimsIdentity = identity as ClaimsIdentity;
+
+ var impersonatorUserIdOrNull = claimsIdentity?.Claims?.FirstOrDefault(c => c.Type == AbpClaimTypes.ImpersonatorUserId);
+ if (impersonatorUserIdOrNull == null || impersonatorUserIdOrNull.Value.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ if (Guid.TryParse(impersonatorUserIdOrNull.Value, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
}
public static ClaimsIdentity AddIfNotContains(this ClaimsIdentity claimsIdentity, Claim claim)
diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs
index 271d5d3d94..da87e89946 100644
--- a/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs
+++ b/framework/src/Volo.Abp.Security/Volo/Abp/Security/Claims/AbpClaimTypes.cs
@@ -67,5 +67,15 @@ namespace Volo.Abp.Security.Claims
/// Default: "client_id".
///
public static string ClientId { get; set; } = "client_id";
+
+ ///
+ /// Default: "impersonator_tenantid".
+ ///
+ public static string ImpersonatorTenantId { get; set; } = "impersonator_tenantid";
+
+ ///
+ /// Default: "impersonator_userid".
+ ///
+ public static string ImpersonatorUserId { get; set; } = "impersonator_userid";
}
}
diff --git a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs
index 43032fe214..d1d75bf16d 100644
--- a/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs
+++ b/framework/src/Volo.Abp.Security/Volo/Abp/Users/CurrentUserExtensions.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using JetBrains.Annotations;
+using Volo.Abp.Security.Claims;
namespace Volo.Abp.Users
{
@@ -30,5 +31,35 @@ namespace Volo.Abp.Users
return currentUser.Id.Value;
}
+
+ public static Guid? FindImpersonatorTenantId([NotNull] this ICurrentUser currentUser)
+ {
+ var impersonatorTenantId = currentUser.FindClaimValue(AbpClaimTypes.ImpersonatorTenantId);
+ if (impersonatorTenantId == null || impersonatorTenantId.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+ if (Guid.TryParse(impersonatorTenantId, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
+ }
+
+ public static Guid? FindImpersonatorUserId([NotNull] this ICurrentUser currentUser)
+ {
+ var impersonatorUserId = currentUser.FindClaimValue(AbpClaimTypes.ImpersonatorUserId);
+ if (impersonatorUserId == null || impersonatorUserId.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+ if (Guid.TryParse(impersonatorUserId, out var guid))
+ {
+ return guid;
+ }
+
+ return null;
+ }
}
-}
\ No newline at end of file
+}
diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpClaimsService.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpClaimsService.cs
index 80c275252c..a977afd2e9 100644
--- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpClaimsService.cs
+++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpClaimsService.cs
@@ -16,6 +16,8 @@ namespace Volo.Abp.IdentityServer
private static readonly string[] AdditionalOptionalClaimNames =
{
AbpClaimTypes.TenantId,
+ AbpClaimTypes.ImpersonatorTenantId,
+ AbpClaimTypes.ImpersonatorUserId,
AbpClaimTypes.Name,
AbpClaimTypes.SurName,
JwtClaimTypes.PreferredUserName,
diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs
index 55121aec99..f75f10d687 100644
--- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs
+++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AbpIdentityServerDomainModule.cs
@@ -107,8 +107,6 @@ namespace Volo.Abp.IdentityServer
identityServerBuilder.AddInMemoryApiResources(configuration.GetSection("IdentityServer:ApiResources"));
identityServerBuilder.AddInMemoryIdentityResources(configuration.GetSection("IdentityServer:IdentityResources"));
}
-
- identityServerBuilder.AddExtensionGrantValidator();
}
public override void PostConfigureServices(ServiceConfigurationContext context)
diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/LinkLoginExtensionGrantValidator.cs b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/LinkLoginExtensionGrantValidator.cs
deleted file mode 100644
index f7422c6a77..0000000000
--- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain/Volo/Abp/IdentityServer/AspNetIdentity/LinkLoginExtensionGrantValidator.cs
+++ /dev/null
@@ -1,152 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Claims;
-using System.Threading.Tasks;
-using IdentityServer4.Validation;
-using Microsoft.Extensions.Localization;
-using Microsoft.Extensions.Logging;
-using Volo.Abp.Identity;
-using Volo.Abp.IdentityServer.Localization;
-using Volo.Abp.MultiTenancy;
-using Volo.Abp.Security.Claims;
-using Volo.Abp.Users;
-using IdentityUser = Volo.Abp.Identity.IdentityUser;
-
-namespace Volo.Abp.IdentityServer.AspNetIdentity
-{
- public class LinkLoginExtensionGrantValidator : IExtensionGrantValidator
- {
- public const string ExtensionGrantType = "LinkLogin";
-
- public string GrantType => ExtensionGrantType;
-
- protected ITokenValidator TokenValidator { get; }
- protected IdentityLinkUserManager IdentityLinkUserManager { get; }
- protected ICurrentTenant CurrentTenant { get; }
- protected ICurrentUser CurrentUser { get; }
- protected ICurrentPrincipalAccessor CurrentPrincipalAccessor { get; }
- protected IdentityUserManager UserManager { get; }
- protected IdentitySecurityLogManager IdentitySecurityLogManager { get; }
- protected ILogger Logger { get; }
- protected IStringLocalizer Localizer { get; }
-
- public LinkLoginExtensionGrantValidator(
- ITokenValidator tokenValidator,
- IdentityLinkUserManager identityLinkUserManager,
- ICurrentTenant currentTenant,
- ICurrentUser currentUser,
- IdentityUserManager userManager,
- ICurrentPrincipalAccessor currentPrincipalAccessor,
- IdentitySecurityLogManager identitySecurityLogManager,
- ILogger logger,
- IStringLocalizer localizer)
- {
- TokenValidator = tokenValidator;
- IdentityLinkUserManager = identityLinkUserManager;
- CurrentTenant = currentTenant;
- CurrentUser = currentUser;
- UserManager = userManager;
- CurrentPrincipalAccessor = currentPrincipalAccessor;
- IdentitySecurityLogManager = identitySecurityLogManager;
- Logger = logger;
- Localizer = localizer;
- }
-
- public virtual async Task ValidateAsync(ExtensionGrantValidationContext context)
- {
- var accessToken = context.Request.Raw["access_token"];
- if (accessToken.IsNullOrWhiteSpace())
- {
- context.Result = new GrantValidationResult
- {
- IsError = true,
- Error = "invalid_access_token"
- };
- return;
- }
-
- var result = await TokenValidator.ValidateAccessTokenAsync(accessToken);
- if (result.IsError)
- {
- context.Result = new GrantValidationResult
- {
- IsError = true,
- Error = result.Error,
- ErrorDescription = result.ErrorDescription
- };
- return;
- }
-
- using (CurrentPrincipalAccessor.Change(result.Claims))
- {
- if (!Guid.TryParse(context.Request.Raw["LinkUserId"], out var linkUserId))
- {
- context.Result = new GrantValidationResult
- {
- IsError = true,
- Error = "invalid_link_user_id"
- };
- return;
- }
-
- Guid? linkTenantId = null;
- if (!context.Request.Raw["LinkTenantId"].IsNullOrWhiteSpace())
- {
- if (!Guid.TryParse(context.Request.Raw["LinkTenantId"], out var parsedGuid))
- {
- context.Result = new GrantValidationResult
- {
- IsError = true,
- Error = "invalid_link_tenant_id"
- };
- return;
- }
-
- linkTenantId = parsedGuid;
- }
-
- var isLinked = await IdentityLinkUserManager.IsLinkedAsync(
- new IdentityLinkUserInfo(CurrentUser.GetId(), CurrentTenant.Id),
- new IdentityLinkUserInfo(linkUserId, linkTenantId),
- true);
-
- if (isLinked)
- {
- using (CurrentTenant.Change(linkTenantId))
- {
- var user = await UserManager.GetByIdAsync(linkUserId);
- var sub = await UserManager.GetUserIdAsync(user);
-
- var additionalClaims = new List();
- await AddCustomClaimsAsync(additionalClaims, user, context);
-
- context.Result = new GrantValidationResult(
- sub,
- GrantType,
- additionalClaims.ToArray()
- );
- }
- }
- else
- {
- context.Result = new GrantValidationResult
- {
- IsError = true,
- Error = Localizer["TheTargetUserIsNotLinkedToYou"]
- };
- }
- }
- }
-
- protected virtual Task AddCustomClaimsAsync(List customClaims, IdentityUser user, ExtensionGrantValidationContext context)
- {
- if (user.TenantId.HasValue)
- {
- customClaims.Add(new Claim(AbpClaimTypes.TenantId, user.TenantId?.ToString()));
- }
-
- return Task.CompletedTask;
- }
- }
-}