2015-02-20 1 views
2

Я использую ASP Identity для аутентификации. Часть Statup.Auth.cs выглядит следующим образом:ASP Идентификационный знак isPersistent не работает

  app.UseCookieAuthentication(
      new CookieAuthenticationOptions 
      { 
       AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
       LoginPath = new PathString("/Account/Login"), 
       Provider = new CookieAuthenticationProvider 
          { 
           // Enables the application to validate the security stamp when the user logs in. 
           // This is a security feature which is used when you change a password or add an external login to your account. 
           OnValidateIdentity = 
            SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
             validateInterval: TimeSpan.FromMinutes(30), 
             regenerateIdentity: 
            (manager, user) => 
            user.GenerateUserIdentityAsync(manager)) 
          }, 
       ExpireTimeSpan = TimeSpan.FromMinutes(Settings.Default.SessionExpireTimeoutInMinutes), 
      }); 

и часть моего Вход метода:

SignInStatus result = await this.SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false); 

Если пользователь выбирает «запомнить меня» вариант, он не должен быть зарегистрирован, пока что-то как 30 дней. Если он не выбирает эту опцию, он должен выйти из системы автоматически через короткий промежуток времени, допустим, 10 минут. В настоящий момент пользователь выходит из системы независимо от того, выбрал ли он эту опцию.

ответ

3

Никто еще не отвечал на этот вопрос?

Известна ошибка в классе SecurityStampValidator, которая предотвращает сохранение свойства isPersistent при сбросе файла cookie аутентификации.

Вопрос supposedly resolved, поэтому вы должны попробовать обновить все свои пакеты, но некоторые люди все еще имеют проблемы.

Способ исправить проблему состоит в том, чтобы написать собственный класс SecurityStampValidator. Вы можете найти версию Microsoft source code here.

Вот код, я попробовал, что похоже на работу (я добавил AuthenticationProperties с AllowRefresh и IsPersistent заданными свойствами):

using Microsoft.Owin.Security.Cookies; 
using Owin; 
using System; 
using System.Security.Claims; 
using System.Threading.Tasks; 
using Microsoft.Owin.Security; 

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<TManager, TUser, string>(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) => 
      { 
       DateTimeOffset currentUtc = DateTimeOffset.UtcNow; 
       if (context.Options != null && context.Options.SystemClock != null) 
       { 
        currentUtc = context.Options.SystemClock.UtcNow; 
       } 
       DateTimeOffset? issuedUtc = context.Properties.IssuedUtc; 

       // Only validate if enough time has elapsed 
       bool validate = (issuedUtc == null); 
       if (issuedUtc != null) 
       { 
        TimeSpan 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).ConfigureAwait(false); 
         bool reject = true; 
         // Refresh the identity if the stamp matches, otherwise reject 
         if (user != null && manager.SupportsUserSecurityStamp) 
         { 
          string securityStamp = context.Identity.FindFirstValue(Constants.DefaultSecurityStampClaimType); 
          if (securityStamp == await manager.GetSecurityStampAsync(userId).ConfigureAwait(false)) 
          { 
           reject = false; 
           // Regenerate fresh claims if possible and resign in 
           if (regenerateIdentityCallback != null) 
           { 
            ClaimsIdentity identity = await regenerateIdentityCallback.Invoke(manager, user); 
            if (identity != null) 
            { 
             var isPersistent = context.Properties.IsPersistent; 
             AuthenticationProperties prop = new AuthenticationProperties(); 
             prop.AllowRefresh = true; //without this, will log out after 30 minutes 
             prop.IsPersistent = isPersistent; //without this, will log out after 30 minutes, or whenever the browser session is ended 
             context.OwinContext.Authentication.SignIn(prop, identity); 
            } 
           } 
          } 
         } 
         if (reject) 
         { 
          context.RejectIdentity(); 
          context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType); 
         } 
        } 
       } 
      }; 
     } 
    } 
} 

Затем вы можете использовать это, изменив SecurityStampValidator к MySecurityStampValidator в файле Startup.Auth.cs, предполагая, что вы используя стандартный шаблон проекта MVC.