2016-12-30 52 views
0

我試圖使用OnValidateIdentity檢查安全標記更改。 但不知何故,當validateInterval用完了我被註銷,並驗證在這裏並不叫regenerateIdentityCallback是startup.cs授權碼Owin CookieAuthentication OnValidateIdentity不會調用regenerateIdentityCallback

app.CreatePerOwinContext(() => 
     { 
      var uow = DependencyResolver.Current.GetService<IUnitOfWork>(); 
      return uow.UsersRepository.UserManager; 
     }); 
     app.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions() 
     { 

      Provider = new CookieAuthenticationProvider() 
      { 
       OnApplyRedirect = context => 
       { 
        if (!context.Request.Path.StartsWithSegments(new PathString("/api"))) 
         context.Response.Redirect(context.RedirectUri); 
       }, 
       OnValidateIdentity = context => SecurityStampValidator.OnValidateIdentity<UserManager<User>, User, string>(
        validateInterval: TimeSpan.FromSeconds(15), 
        regenerateIdentityCallback: (mngr, usr) => 
        { 
         Debug.WriteLine("Regenerate identity"); 
         var rolesStr = (mngr.GetRoles(usr.Id)).ToArray(); 
         return AccountController.CreateClaims(usr, rolesStr); 
        }, 
        getUserIdCallback: ci => 
        { 
         return ci.GetUserId(); 
        }).Invoke(context) 
      }, 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      LoginPath = new PathString("/Account/"), 
      CookieName = "Alisary", 
      ExpireTimeSpan = TimeSpan.FromMinutes(20), 
      SlidingExpiration = false, 
     }); 

UserManger是在DAL層。代碼:

public UserRepository(DatabaseContext context, IDataProtectionProvider dataProtection) 
    { 
     this.context = context; 
     this.dataProtectionProvider = dataProtection; 
     userManager = new UserManager<User>(
      new UserStore<User>(context)); 
     userManager.EmailService = new EmailSenderService(); 
     userManager.UserTokenProvider = new DataProtectorTokenProvider<User>(
      dataProtection.Create("protectionKey")) 
     { 
      TokenLifespan = TimeSpan.FromHours(24) 
     }; 
     userManager.UserValidator = new UserValidator<User>(userManager) 
     { 
      AllowOnlyAlphanumericUserNames = false, 
      RequireUniqueEmail = true 
     }; 
     userManager.PasswordValidator = new PasswordValidator() 
     { 
      RequiredLength = 6, 

     }; 


     roleManager = new RoleManager<IdentityRole>(
      new RoleStore<IdentityRole>(context)); 

    } 

上下文是數據庫上下文。

+0

嘗試用'OnValidateIdentity =上下文=> SecurityStampValidator.OnValidateIdentity ( validateInterval:TimeSpan.FromSeconds(30), regenerateIdentityCallback: (經理,用戶)=> user.GenerateUserIdentityAsync(經理context.Identity), getUserIdCallback:(ci)=> Guid.Parse(ci.GetUserId()))。Invoke(context)' – Hackerman

+0

我不使用ApplicationUserManager,我在DAL層中使用一個自定義的。但是當我改變字符串Guid我得到'類型UserManager 不能用作類型參數TManger不存在從UserManager 到UserManger '的隱式轉換。我也會用生成我的用戶管理器的代碼更新我的問題。 –

回答

1

我設法解決我的問題,使用完全自定義驗證提供程序,而不是使用SecurityStampValidator。

類似這樣的東西代碼:

Provider = new CookieAuthenticationProvider() 
      { 
       OnApplyRedirect = context => 
       { 
        if (!context.Request.Path.StartsWithSegments(new PathString("/api"))) 
         context.Response.Redirect(context.RedirectUri); 
       }, 
       OnValidateIdentity = async context => 
       { 
        var uow = DependencyResolver.Current.GetService<IUnitOfWork>(); 
        var user = await uow.UsersRepository.FindUserByIdAsync(context.Identity.GetUserId()); 
        uow.Reload(user); 
        var oldSecurityStamp = (context.Identity as ClaimsIdentity) 
      .Claims.Where(x => x.Type.Equals(ClaimTypes.Expiration)) 
      .FirstOrDefault().Value; 

        if (!user.SecurityStamp.Equals(oldSecurityStamp)) 
        { 
         context.RejectIdentity(); 
         context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType); 
        } 
       } 
       /*SecurityStampValidator.OnValidateIdentity<UserManager<User>, User, string>(
        validateInterval: TimeSpan.FromSeconds(15), 
        regenerateIdentityCallback: (mngr, usr) => 
        { 
         Debug.WriteLine("Regenerate identity"); 
         var rolesStr = (mngr.GetRoles(usr.Id)).ToArray(); 
         return AccountController.CreateClaims(usr, rolesStr); 
        }, 
        getUserIdCallback: ci => 
        { 
         return ci.GetUserId(); 
        }).Invoke(context)*/ 
      }, 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      LoginPath = new PathString("/Account/"), 
      CookieName = "Alisary", 
      ExpireTimeSpan = TimeSpan.FromMinutes(20), 
      SlidingExpiration = true, 
     }); 

這段代碼的唯一問題是,它檢查並擊中了數據庫這是很好的,以我的每授權的請求,現在知道這會不會被打普通人。

此外,如果有任何解決方案使用SecurityStampValidator,我仍然打開建議。

謝謝。