Last active
July 29, 2021 18:51
-
-
Save trailmax/e51790f31c8c68749ec0 to your computer and use it in GitHub Desktop.
SecurityStampValidator from Microsoft.AspNet.Identity.Owin - taken from decompiler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Security.Claims; | |
using System.Threading.Tasks; | |
using Microsoft.Owin.Security.Cookies; | |
namespace Microsoft.AspNet.Identity.Owin | |
{ | |
/// <summary> | |
/// Static helper class used to configure a CookieAuthenticationProvider to validate a cookie against a user's security | |
/// stamp | |
/// </summary> | |
public static class MySecurityStampValidator | |
{ | |
/// <summary> | |
/// Can be used as the ValidateIdentity method for a CookieAuthenticationProvider which will check a user's security | |
/// stamp after validateInterval | |
/// Rejects the identity if the stamp changes, and otherwise will call regenerateIdentity to sign in a new | |
/// ClaimsIdentity | |
/// </summary> | |
/// <typeparam name="TManager"></typeparam> | |
/// <typeparam name="TUser"></typeparam> | |
/// <param name="validateInterval"></param> | |
/// <param name="regenerateIdentity"></param> | |
/// <returns></returns> | |
public static Func<CookieValidateIdentityContext, Task> OnValidateIdentity<TManager, TUser>( | |
TimeSpan validateInterval, Func<TManager, TUser, Task<ClaimsIdentity>> regenerateIdentity) | |
where TManager : UserManager<TUser, string> | |
where TUser : class, IUser<string> | |
{ | |
return OnValidateIdentity(validateInterval, regenerateIdentity, id => id.GetUserId()); | |
} | |
/// <summary> | |
/// Can be used as the ValidateIdentity method for a CookieAuthenticationProvider which will check a user's security | |
/// stamp after validateInterval | |
/// Rejects the identity if the stamp changes, and otherwise will call regenerateIdentity to sign in a new | |
/// ClaimsIdentity | |
/// </summary> | |
/// <typeparam name="TManager"></typeparam> | |
/// <typeparam name="TUser"></typeparam> | |
/// <typeparam name="TKey"></typeparam> | |
/// <param name="validateInterval"></param> | |
/// <param name="regenerateIdentityCallback"></param> | |
/// <param name="getUserIdCallback"></param> | |
/// <returns></returns> | |
public static Func<CookieValidateIdentityContext, Task> OnValidateIdentity<TManager, TUser, TKey>( | |
TimeSpan validateInterval, Func<TManager, TUser, Task<ClaimsIdentity>> regenerateIdentityCallback, | |
Func<ClaimsIdentity, TKey> getUserIdCallback) | |
where TManager : UserManager<TUser, TKey> | |
where TUser : class, IUser<TKey> | |
where TKey : IEquatable<TKey> | |
{ | |
return async context => | |
{ | |
var currentUtc = DateTimeOffset.UtcNow; | |
if (context.Options != null && context.Options.SystemClock != null) | |
{ | |
currentUtc = context.Options.SystemClock.UtcNow; | |
} | |
var issuedUtc = context.Properties.IssuedUtc; | |
// Only validate if enough time has elapsed | |
var validate = (issuedUtc == null); | |
if (issuedUtc != null) | |
{ | |
var timeElapsed = currentUtc.Subtract(issuedUtc.Value); | |
validate = timeElapsed > validateInterval; | |
} | |
if (validate) | |
{ | |
var manager = context.OwinContext.GetUserManager<TManager>(); | |
var userId = getUserIdCallback(context.Identity); | |
if (manager != null && userId != null) | |
{ | |
var user = await manager.FindByIdAsync(userId).WithCurrentCulture(); | |
var reject = true; | |
// Refresh the identity if the stamp matches, otherwise reject | |
if (user != null && manager.SupportsUserSecurityStamp) | |
{ | |
var securityStamp = | |
context.Identity.FindFirstValue(Constants.DefaultSecurityStampClaimType); | |
if (securityStamp == await manager.GetSecurityStampAsync(userId).WithCurrentCulture()) | |
{ | |
reject = false; | |
// Regenerate fresh claims if possible and resign in | |
if (regenerateIdentityCallback != null) | |
{ | |
var identity = await regenerateIdentityCallback.Invoke(manager, user); | |
if (identity != null) | |
{ | |
// here you need to do magic with the context | |
// should contain previous cookie value if it was set to be persistent. | |
var isPersistent = context.Properties.IsPersistent; | |
// and now you should set this flag on the new cookie | |
context.OwinContext.Authentication.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, userIdentity); | |
} | |
} | |
} | |
} | |
if (reject) | |
{ | |
context.RejectIdentity(); | |
context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType); | |
} | |
} | |
} | |
}; | |
} | |
} | |
} |
greate snippet. thanks
Thanks for sharing
Man! You're Awesome! This totally worked for my IsPersistent flag not being correctly set by the default Identity behaviour
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Looks like you've got a typo on #96, should be
identity
notuserIdentity
I assume.