C# Owin CookieAuthentication OnValidateIdentity不';t调用重新生成标识回调

C# Owin CookieAuthentication OnValidateIdentity不';t调用重新生成标识回调,c#,asp.net-mvc,C#,Asp.net Mvc,我正在尝试使用OnValidateIdentity检查安全戳的更改。 但不知怎的,当validateInterval用完时,我注销了,验证器没有调用regenerateIdentityCallback这里是startup.cs中的身份验证代码 app.CreatePerOwinContext(() => { var uow = DependencyResolver.Current.GetService<IUnitOfWork>();

我正在尝试使用OnValidateIdentity检查安全戳的更改。 但不知怎的,当validateInterval用完时,我注销了,验证器没有调用regenerateIdentityCallback这里是startup.cs中的身份验证代码

  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,
        });
app.CreatePerOwinContext(()=>
{
var uow=DependencyResolver.Current.GetService();
返回uow.UsersRepository.UserManager;
});
app.UseCookieAuthentication(新的Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions()
{
Provider=新CookieAuthenticationProvider()
{
OnApplyRedirect=context=>
{
if(!context.Request.Path.StartsWithSegments(新路径字符串(“/api”)))
context.Response.Redirect(context.RedirectUri);
},
OnValidateIdentity=context=>SecurityStampValidator.OnValidateIdentity(
validateInterval:TimeSpan.FromSeconds(15),
重新生成标识回调:(mngr,usr)=>
{
Debug.WriteLine(“重新生成标识”);
var rolesStr=(mngr.GetRoles(usr.Id)).ToArray();
return AccountController.CreateClaims(usr,rolesStr);
},
getUserIdCallback:ci=>
{
返回ci.GetUserId();
}).Invoke(上下文)
},
AuthenticationType=DefaultAuthenticationTypes.ApplicationOkie,
LoginPath=新路径字符串(“/Account/”,
CookieName=“Alisary”,
ExpireTimeSpan=从分钟(20)开始的时间跨度,
slidengexpiration=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));

    }
公共用户存储库(DatabaseContext上下文,IDataProtectionProvider dataProtection) { this.context=上下文; this.dataProtectionProvider=dataProtection; userManager=新的userManager( 新用户存储(上下文); userManager.EmailService=新的EmailSenderService(); userManager.UserTokenProvider=新的DataProtectorTokenProvider( dataProtection.Create(“protectionKey”)) { 令牌寿命=时间跨度。从小时(24) }; userManager.UserValidator=新的UserValidator(userManager) { AllowOnlyAlphanumericUserNames=false, RequireUniqueEmail=true }; userManager.PasswordValidator=新的PasswordValidator() { 所需长度=6, }; 角色管理器=新角色管理器( 新RoleStore(上下文); }
上下文是数据库上下文。

我使用完全自定义的验证提供程序解决了问题,而不是使用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,
        });
Provider=新CookieAuthenticationProvider()
{
OnApplyRedirect=context=>
{
if(!context.Request.Path.StartsWithSegments(新路径字符串(“/api”)))
context.Response.Redirect(context.RedirectUri);
},
OnValidateIdentity=异步上下文=>
{
var uow=DependencyResolver.Current.GetService();
var user=await uow.UsersRepository.FindUserByIdAsync(context.Identity.GetUserId());
uow.重新加载(用户);
var oldSecurityStamp=(context.Identity作为ClaimsIdentity)
.Claims.Where(x=>x.Type.Equals(ClaimTypes.Expiration))
.FirstOrDefault()值;
如果(!user.SecurityStamp.Equals(oldSecurityStamp))
{
context.RejectIdentity();
context.OwinContext.Authentication.SignOut(context.Options.AuthenticationType);
}
}
/*SecurityStampValidator.OnValidateIdentity(
validateInterval:TimeSpan.FromSeconds(15),
重新生成标识回调:(mngr,usr)=>
{
Debug.WriteLine(“重新生成标识”);
var rolesStr=(mngr.GetRoles(usr.Id)).ToArray();
return AccountController.CreateClaims(usr,rolesStr);
},
getUserIdCallback:ci=>
{
返回ci.GetUserId();
}).Invoke(上下文)*/
},
AuthenticationType=DefaultAuthenticationTypes.ApplicationOkie,
LoginPath=新路径字符串(“/Account/”,
CookieName=“Alisary”,
ExpireTimeSpan=从分钟(20)开始的时间跨度,
slidengexpiration=true,
});
关于这段代码的唯一问题是,它检查并在每个授权请求上命中数据库,这对我来说很好,现在我知道这不会被普通人命中

此外,如果有任何使用SecurityStampValidator的解决方案,我仍然愿意接受建议


谢谢。

您在每次调用时都会调用一个新的
SecurityStampValidator.OnValidateIdentity
。要解决此问题,请在…之前创建它


var validator=SecurityStampValidator
.OnValidateId实体(
validateInterval:TimeSpan.FromSeconds(2),
regenerateIdentityCallback:(管理器,用户)=>user.GenerateUserIdentityAsync(管理器),
getUserIdCallback:(id)=>id.GetUserGuid());
var cookieAuthenticationOptions=新的cookieAuthenticationOptions
{
Provider=新CookieAuthenticationProvider
{
//没有被召唤去签名
OnValidateIdentity=上下文=>
{
返回validator.Invoke(上下文);
}
}
};
或者在没有上下文的情况下这样做