我正在尝试使用OnValidateIdentity来检查安全标记更改。 但不知怎的,当validateInterval用完时我退出了,验证器没有调用regenerateIdentityCallback这里是来自startup.cs的auth代码
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));
}
context是数据库上下文。
答案 0 :(得分: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,我仍然可以提出建议。感谢。
答案 1 :(得分:1)
您每次通话都在调用一个新的SecurityStampValidator.OnValidateIdentity
。为了解决这个问题,请在...之前创建它
var validator = SecurityStampValidator
.OnValidateIdentity<ApplicationUserManager, ApplicationUser, Guid>(
validateInterval: TimeSpan.FromSeconds(2),
regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
getUserIdCallback: (id) => id.GetUserGuid());
var cookieAuthenticationOptions = new CookieAuthenticationOptions
{
Provider = new CookieAuthenticationProvider
{
// Not called on signin
OnValidateIdentity = context =>
{
return validator.Invoke(context);
}
}
};
或者在没有上下文的情况下完成
var cookieAuthenticationOptions = new CookieAuthenticationOptions
{
Provider = new CookieAuthenticationProvider
{
// Not called on signin
OnValidateIdentity = validator,
}
};