solution:
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.RemoveAll(x => x.ImplementationType == typeof(ImpersonationExtensionGrantValidator));
context.Services.AddTransient<IExtensionGrantValidator, MyImpersonationExtensionGrantValidator>();
}
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 Microsoft.Extensions.Options;
using Volo.Abp.Account.Localization;
using Volo.Abp.Account.Public.Web;
using Volo.Abp.Account.Web.ExtensionGrantValidators;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Security.Claims;
using Volo.Abp.Users;
namespace MyCompanyName.MyProjectName;
public class MyImpersonationExtensionGrantValidator : ImpersonationExtensionGrantValidator
{
private readonly ITenantStore _tenantStore;
public MyImpersonationExtensionGrantValidator(
ITokenValidator tokenValidator,
IPermissionChecker permissionChecker,
ICurrentTenant currentTenant,
ICurrentUser currentUser,
IdentityUserManager userManager,
ICurrentPrincipalAccessor currentPrincipalAccessor,
IdentitySecurityLogManager identitySecurityLogManager,
ILogger<MyImpersonationExtensionGrantValidator> logger,
IStringLocalizer<AccountResource> localizer,
IOptions<AbpAccountOptions> abpAccountOptions,
Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory<IdentityUser> claimsFactory, ITenantStore tenantStore)
: base(tokenValidator, permissionChecker, currentTenant, currentUser, userManager, currentPrincipalAccessor, identitySecurityLogManager, logger, localizer, abpAccountOptions, claimsFactory)
{
_tenantStore = tenantStore;
}
protected async override Task ImpersonateUserAsync(ExtensionGrantValidationContext context, Guid? tenantId, Guid userId)
{
if (userId == CurrentUser.Id)
{
context.Result = new GrantValidationResult
{
IsError = true,
Error = Localizer["Volo.Account:YouCanNotImpersonateYourself"]
};
return;
}
if (AbpAccountOptions.ImpersonationUserPermission.IsNullOrWhiteSpace() ||
await PermissionChecker.IsGrantedAsync(AbpAccountOptions.ImpersonationUserPermission))
{
using (CurrentTenant.Change(tenantId))
{
var user = await UserManager.FindByIdAsync(userId.ToString());
if (user != null)
{
var sub = await UserManager.GetUserIdAsync(user);
var additionalClaims = new List<Claim>();
if (CurrentUser.Id?.ToString() != CurrentUser.FindClaim(AbpClaimTypes.ImpersonatorUserId)?.Value)
{
additionalClaims.Add(new Claim(AbpClaimTypes.ImpersonatorUserId, CurrentUser.Id.ToString()));
additionalClaims.Add(new Claim(AbpClaimTypes.ImpersonatorUserName, CurrentUser.UserName));
if (CurrentTenant.IsAvailable)
{
additionalClaims.Add(new Claim(AbpClaimTypes.ImpersonatorTenantId, CurrentTenant.Id.ToString()));
var tenantConfiguration = await _tenantStore.FindAsync(CurrentTenant.Id.Value);
if (tenantConfiguration != null && !tenantConfiguration.Name.IsNullOrWhiteSpace())
{
additionalClaims.Add(new Claim(AbpClaimTypes.ImpersonatorTenantName, tenantConfiguration.Name));
}
}
}
await AddCustomClaimsAsync(additionalClaims, user, context);
context.Result = new GrantValidationResult(
sub,
GrantType,
additionalClaims.ToArray()
);
//save security log to user.
var userPrincipal = await ClaimsFactory.CreateAsync(user);
userPrincipal.Identities.First().AddClaims(additionalClaims);
using (CurrentPrincipalAccessor.Change(userPrincipal))
{
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext
{
Identity = IdentitySecurityLogIdentityConsts.Identity,
Action = "ImpersonateUser"
});
}
}
else
{
context.Result = new GrantValidationResult
{
IsError = true,
Error = Localizer["Volo.Account:ThereIsNoUserWithId"].ToString()
.Replace("{UserId}", userId.ToString())
};
}
}
}
else
{
context.Result = new GrantValidationResult
{
IsError = true,
Error = Localizer["Volo.Account:RequirePermissionToImpersonateUser"].ToString()
.Replace("{PermissionName}", AbpAccountOptions.ImpersonationUserPermission)
};
}
}
}
hi
I will check this.
Hi
Azure has a document that you can refer to.
https://docs.microsoft.com/en-us/azure/app-service/troubleshoot-http-502-http-503
ok liming.ma@volosoft.com
Please share the logs when the request is slowly.
Please try to remove the Trusted_Connection=True;
User ID and Password are specified and
Trusted_Connectionis set to true, the User ID and Password will be ignored and Integrated Security will be used.
hi
You can override the public virtual async Task<IActionResult> OnGetExternalLoginCallbackAsync(string returnUrl = "", string returnUrlHash = "", string remoteError = null) method of account\src\Volo.Abp.Account.Pro.Public.Web.IdentityServer\Pages\Account\IdentityServerSupportedLoginModel.cs.
Check the current tenant and ExternalLoginInfo
See https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Guide
hi
You're right.
IAbpAuthorizationExceptionHandler doesn't format 403 response as a valid abp format error reponse. Not sure why.
The reason: https://github.com/abpframework/abp/issues/9926#issue-983402382
You can directly display an error message.
HTTP 403 is returned when the client is not permitted access to the resource despite providing authentication such as insufficient permissions of the authenticated account.