One thing which I have learnt from working with Identity Server is that, out of the box, ASP.NET Core Identity does not play too well with Identity Server. Refer to this question.
ASP.NET Identity contains a way of ejecting users where a particular user's data has changed. This is regulated by the SecurityStamp column of the aspnetuser table. When the stamp changes, the next time the cookie is validated, it fails validation.
This is turned on by default and it is the reason why it does not work well with Identity Server.
You end up with users getting kicked out erratically. And when you expect it to kick users out, it doesn't.
Anyhow, how do you disable this feature of ASP.NET Identity???
There is a column on the UserManager called SupportsUserSecurityStamp.
However, it is a "getter" only and I cannot find any configuration setting for switching that to return false
.
It seems to me that the only way is to derive from the UserManager class and make that property only ever return false
.
That feels like a hack. Especially when you look at the code for that property on Github:
public virtual bool SupportsUserSecurityStamp
{
get
{
ThrowIfDisposed();
return Store is IUserSecurityStampStore<TUser>;
}
}
Is there a "proper way" to turn the SecurityStamp feature of ASP.NET Identity off?
Sidenote: at the moment, we have a bandaid solution of making a huge validation time huge by this configuration-
services.Configure<SecurityStampValidatorOptions>(
o => o.ValidationInterval = TimeSpan.FromHours(SecurityTimestampDuration)
);
All this achieves is making a huge window between validation of the stamp. But turning the feature off completely is more desirable.
Cheers
I turned the SecurityStamp
feature off, as described in the question.
So, I created a class which inherits from the UserManager
class.
Should look something like this:
public class IcUserManager : UserManager<IdpUser>
{
public IcUserManager(IUserStore<IdpUser> store,
IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<IdpUser> passwordHasher,
IEnumerable<IUserValidator<IdpUser>> userValidators,
IEnumerable<IPasswordValidator<IdpUser>> passwordValidators,
ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors,
IServiceProvider services,
ILogger<UserManager<IdpUser>> logger)
: base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
{
}
public override bool SupportsUserSecurityStamp => false;
}
By setting SupportsUserSecurityStamp
to false, it immediately exits that validation check in the framework.