It works for me.
public class MySignInManager : AbpSignInManager
{
public MySignInManager(
IdentityUserManager userManager,
IHttpContextAccessor contextAccessor,
IUserClaimsPrincipalFactory<IdentityUser> claimsFactory,
IOptions<IdentityOptions> optionsAccessor,
ILogger<SignInManager<IdentityUser>> logger,
IAuthenticationSchemeProvider schemes,
IUserConfirmation<IdentityUser> confirmation,
IOptions<AbpIdentityOptions> options) :
base(userManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation, options)
{
}
private async Task<bool> IsTfaEnabled(IdentityUser user)
=> UserManager.SupportsUserTwoFactor &&
await UserManager.GetTwoFactorEnabledAsync(user) &&
(await UserManager.GetValidTwoFactorProvidersAsync(user)).Count > 0;
public override async Task<SignInResult> CheckPasswordSignInAsync(
IdentityUser user,
string password,
bool lockoutOnFailure)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var error = await PreSignInCheck(user);
if (error != null)
{
return error;
}
if (await UserManager.CheckPasswordAsync(user, password))
{
var alwaysLockout = AppContext
.TryGetSwitch("Microsoft.AspNetCore.Identity.CheckPasswordSignInAlwaysResetLockoutOnSuccess", out var enabled) && enabled;
// Only reset the lockout when not in quirks mode if either TFA is not enabled or the client is remembered for TFA.
if (alwaysLockout || !await IsTfaEnabled(user) || await IsTwoFactorClientRememberedAsync(user))
{
await ResetLockout(user);
}
await UserManager.UpdateSecurityStampAsync(user);
return SignInResult.Success;
}
Logger.LogWarning(2, "User failed to provide the correct password.");
if (UserManager.SupportsUserLockout && lockoutOnFailure)
{
// If lockout is requested, increment access failed count which might lock out the user
await UserManager.AccessFailedAsync(user);
if (await UserManager.IsLockedOutAsync(user))
{
return await LockedOut(user);
}
}
return SignInResult.Failed;
}
}
public override void PreConfigureServices(ServiceConfigurationContext context)
{
..................
PreConfigure<IdentityBuilder>(builder =>
{
builder
.AddSignInManager<MySignInManager>();
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
............
Configure<SecurityStampValidatorOptions>(options =>
{
options.ValidationInterval = TimeSpan.FromSeconds(5);
});
...........
}
Hi,
You can override the CheckPasswordSignInAsync
method of SignInManager
class
public override async Task<SignInResult> CheckPasswordSignInAsync(
IdentityUser user,
string password,
bool lockoutOnFailure)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
var error = await PreSignInCheck(user);
if (error != null)
{
return error;
}
if (await UserManager.CheckPasswordAsync(user, password))
{
var alwaysLockout = AppContext
.TryGetSwitch("Microsoft.AspNetCore.Identity.CheckPasswordSignInAlwaysResetLockoutOnSuccess", out var enabled) && enabled;
// Only reset the lockout when not in quirks mode if either TFA is not enabled or the client is remembered for TFA.
if (alwaysLockout || !await IsTfaEnabled(user) || await IsTwoFactorClientRememberedAsync(user))
{
await ResetLockout(user);
}
await UserManager.UpdateSecurityStampAsync(user);
return SignInResult.Success;
}
Logger.LogWarning(2, "User failed to provide the correct password.");
if (UserManager.SupportsUserLockout && lockoutOnFailure)
{
// If lockout is requested, increment access failed count which might lock out the user
await UserManager.AccessFailedAsync(user);
if (await UserManager.IsLockedOutAsync(user))
{
return await LockedOut(user);
}
}
return SignInResult.Failed;
}
Hi,
Try:
Configure<SecurityStampValidatorOptions>(options =>
{
options.ValidationInterval = TimeSpan.FromSeconds(5);
});
Sure, please email me.
Hi,
We need a project and steps to reproduce the problem, if you can provide them, we can help you solve the problem quickly. You can email me: shiwei.liang@volosoft.com
Yes.
If the specified configuration is not provided, it will fallback to default.
Hi,
You can put the class these Class to .Web
project.
Add the following code to the ConfigureServices
method of .WebModule
context.Services.Replace(ServiceDescriptor.Transient<IClaimsService, MyAbpClaimsService>());
How I can get the claim to check the user property ConCurrentUserID, so that I can block login?
If you are not logged in, you cannot get the user claim, You should query the database values.
Hi,
You can try:
public class MyAbpClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
{
public Task ContributeAsync(AbpClaimsPrincipalContributorContext context)
{
var claimsIdentity = new ClaimsIdentity();
claimsIdentity.AddIfNotContains(new Claim("ConCurrentUserId", "value"));
context.ClaimsPrincipal.AddIdentity(claimsIdentity);
return Task.CompletedTask;
}
}
public class MyAbpClaimsService : AbpClaimsService
{
public MyAbpClaimsService(IProfileService profile, ILogger<DefaultClaimsService> logger) : base(profile, logger)
{
}
protected override IEnumerable<string> FilterRequestedClaimTypes(IEnumerable<string> claimTypes)
{
return base.FilterRequestedClaimTypes(claimTypes)
.Union(new []{
AbpClaimTypes.TenantId,
AbpClaimTypes.EditionId,
"ConCurrentUserId"
});
}
}
context.Services.Replace(ServiceDescriptor.Transient<IClaimsService, MyAbpClaimsService>());
Hi,
Yes we can.
You need to reference the AbpIdentityHttpApiClientModule
module.
See https://docs.abp.io/en/abp/latest/API/Dynamic-CSharp-API-Clients#usage
Like:
{
"RemoteServices": {
"AbpIdentity": {
"BaseUrl": "http://localhost:48392/"
}
}
}