Should i put the following in ConfigureServices or PreConfigureServices in the *WebModule
*.web
project
context.Services.AddScoped<MyAbpSecurityStampValidator>();
context.Services.AddScoped(typeof(SecurityStampValidator<IdentityUser>), provider => provider.GetService(typeof(MyAbpSecurityStampValidator)));
context.Services.AddScoped(typeof(ISecurityStampValidator), provider => provider.GetService(typeof(MyAbpSecurityStampValidator)));
i cant see the brach dud you publish to origin ?
Sure how would you like to connect ?
Teams
I have done exactly what you have done but it doesn't work i am logged out after 5 seconds
using IdentityServer4.Events;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.Guids;
using Volo.Abp.Identity;
using Volo.Abp.Identity.AspNetCore;
using Volo.Abp.Security.Claims;
using IdentityUser = Volo.Abp.Identity.IdentityUser;
namespace DesertFire.Ppm.Web
{
public class PpmSignInManager : AbpSignInManager
{
public PpmSignInManager(
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 TFA is not enabled when not in quirks mode
if (alwaysLockout || !await IsTfaEnabled(user) || await IsTwoFactorClientRememberedAsync(user))
{
await ResetLockout(user);
}
await UserManager.UpdateSecurityStampAsync(user);
return SignInResult.Success;
}
Logger.LogWarning(2, "User {userId} failed to provide the correct password.", await UserManager.GetUserIdAsync(user));
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)
{
context.Services.PreConfigure<AbpMvcDataAnnotationsLocalizationOptions>(options =>
{
options.AddAssemblyResource(
typeof(PpmResource),
typeof(PpmDomainModule).Assembly,
typeof(PpmDomainSharedModule).Assembly,
typeof(PpmApplicationModule).Assembly,
typeof(PpmApplicationContractsModule).Assembly,
typeof(PpmWebModule).Assembly
);
});
PreConfigure<IdentityBuilder>(identityBuilder =>
{
identityBuilder.AddSignInManager<PpmSignInManager>();
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
var hostingEnvironment = context.Services.GetHostingEnvironment();
var configuration = context.Services.GetConfiguration();
ConfigureBundles();
ConfigureUrls(configuration);
ConfigurePages(configuration);
ConfigureCache(configuration);
ConfigureAuthentication(context, configuration);
ConfigureAutoMapper();
ConfigureVirtualFileSystem(hostingEnvironment);
ConfigureNavigationServices();
ConfigureAutoApiControllers();
ConfigureSwaggerServices(context.Services);
ConfigureCors(context, configuration);
ConfigureExternalProviders(context);
//context.Services.Replace(ServiceDescriptor.Transient<IClaimsService, PpmAbpClaimsService>());
Configure<SecurityStampValidatorOptions>(options =>
{
options.ValidationInterval = TimeSpan.FromSeconds(5);
});
}
Okay The Validate methods are now hitting in my cutom SiginManager but i can't login as a current user seems i get a user is null
what is the best place to call the below so that i can make all previous sessions in all browsers invalid and just let the current user login?
if (user != null) { await UserManager.UpdateSecurityStampAsync(user); }
Having a GUID stored as i previously thought will not be a good solution. I am trying to update the security stamp as done in aspnetzero but it doesn't appear towork in abp.io
public override async Task SignInWithClaimsAsync(Volo.Abp.Identity.IdentityUser user, AuthenticationProperties authenticationProperties, IEnumerable<Claim> additionalClaims)
{
var userPrincipal = await CreateUserPrincipalAsync(user);
foreach (var claim in additionalClaims)
{
userPrincipal.Identities.First().AddClaim(claim);
}
await Context.SignInAsync(IdentityConstants.ApplicationScheme,
userPrincipal,
authenticationProperties ?? new AuthenticationProperties());
await UserManager.UpdateSecurityStampAsync(user);
}
can you please let me know why the above code doesn't work, when ii test my presios sessions in other browsers are not loged out and invalidated
hi
Add an property to User, you can use GUID. Change this value after each login and store it in current cliaims.
If you find that this value has changed, it means the user is logged in again. so tyou can block login
This is not a good solution what if the user forgets to logout, the user wont be allowed to log back in if the GIU is not removed right?
and when you say store it in the current claim what doyou mean?
@liangshiwei can you please let me know which project I put these Class's in *.application
? . and where does do i put the following line in ... Configure Servcies
?
context.Services.Replace(ServiceDescriptor.Transient<IClaimsService, MyAbpClaimsService>());
if I am right this just adds the Custom Claim ..... I still have to modify the SignInManager
to check if the value of ConCurrentUserId has changed and block login .... am i correct?
If so which Method in the SignInManager
should i use?