我有一个在用户登录时设置的cookie,如下所示:
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/User/Login"),
CookieName = "LoginCookie",
ExpireTimeSpan = TimeSpan.FromHours(3),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromHours(3),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
基本上没有什么特别的,它只是用户登录时定义的简单cookie以及持续时间。现在,我想在此处定义一种方法,以了解该Cookie在xx小时(以我的情况为3小时)过期后会发生什么情况。
在这一部分中,我可以看到要定义的方法:
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromHours(8),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
该方法称为“ OnResponseSignOut”,所以我想知道这是否是我想要的吗?
基本上,一旦用户的cookie过期,在将他重定向到登录页面进行重新登录之前,我想将其在数据库中的登录会话更改为“ false”,如下所示:
var loggedSession = context.LoginSessions.FirstOrDefault(y=>y.UserId == 55 && y.SessionId == Session.SessionID);
loggedSession.LoggedIn = false;
我怎么能做到这一点?
答案 0 :(得分:0)
您可以创建 SecurityStampValidator 的副本:
public static class MySecurityStampValidator
{
private const string DefaultSecurityStampClaimType = "AspNet.Identity.SecurityStamp";
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());
}
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>
{
if (getUserIdCallback == null)
{
throw new ArgumentNullException("getUserIdCallback");
}
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(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).WithCurrentCulture();
if (identity != null)
{
// Fix for regression where this value is not updated
// Setting it to null so that it is refreshed by the cookie middleware
context.Properties.IssuedUtc = null;
context.Properties.ExpiresUtc = null;
context.OwinContext.Authentication.SignIn(context.Properties, identity);
}
}
}
}
if (reject)
{
// do what you need
var ctx = context.OwinContext.Get<YourDbContext>();
var loggedSession = ctx.LoginSessions.FirstOrDefault(y => y.UserId == 55 && y.SessionId == Session.SessionID);
loggedSession.LoggedIn = false;
ctx.SaveChanges();
context.RejectIdentity();
context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
}
}
}
};
}
}
不要忘记复制ASPNET Identity TaskExtensions 类,因为需要它来保留线程上的区域性:
internal static class TaskExtensions
{
public static CultureAwaiter<T> WithCurrentCulture<T>(this Task<T> task)
{
return new CultureAwaiter<T>(task);
}
public static CultureAwaiter WithCurrentCulture(this Task task)
{
return new CultureAwaiter(task);
}
public struct CultureAwaiter<T> : ICriticalNotifyCompletion
{
private readonly Task<T> _task;
public CultureAwaiter(Task<T> task)
{
_task = task;
}
public CultureAwaiter<T> GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return _task.IsCompleted; }
}
public T GetResult()
{
return _task.GetAwaiter().GetResult();
}
public void OnCompleted(Action continuation)
{
// The compiler will never call this method
throw new NotImplementedException();
}
public void UnsafeOnCompleted(Action continuation)
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
_task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() =>
{
var originalCulture = Thread.CurrentThread.CurrentCulture;
var originalUiCulture = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
try
{
continuation();
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
Thread.CurrentThread.CurrentUICulture = originalUiCulture;
}
});
}
}
public struct CultureAwaiter : ICriticalNotifyCompletion
{
private readonly Task _task;
public CultureAwaiter(Task task)
{
_task = task;
}
public CultureAwaiter GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return _task.IsCompleted; }
}
public void GetResult()
{
_task.GetAwaiter().GetResult();
}
public void OnCompleted(Action continuation)
{
// The compiler will never call this method
throw new NotImplementedException();
}
public void UnsafeOnCompleted(Action continuation)
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
var currentUiCulture = Thread.CurrentThread.CurrentUICulture;
_task.ConfigureAwait(false).GetAwaiter().UnsafeOnCompleted(() =>
{
var originalCulture = Thread.CurrentThread.CurrentCulture;
var originalUiCulture = Thread.CurrentThread.CurrentUICulture;
Thread.CurrentThread.CurrentCulture = currentCulture;
Thread.CurrentThread.CurrentUICulture = currentUiCulture;
try
{
continuation();
}
finally
{
Thread.CurrentThread.CurrentCulture = originalCulture;
Thread.CurrentThread.CurrentUICulture = originalUiCulture;
}
});
}
}
}
分配SecurityStamp验证程序:
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = MySecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromHours(8),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
}
您完成了。