C# Owin CookieAuthentication OnValidateIdentity不';t调用重新生成标识回调
我正在尝试使用OnValidateIdentity检查安全戳的更改。 但不知怎的,当validateInterval用完时,我注销了,验证器没有调用regenerateIdentityCallback这里是startup.cs中的身份验证代码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>();
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(上下文);
}
}
};
或者在没有上下文的情况下这样做