C# ASP.NET标识2使标识无效困难
我今天一整天都在更新ASP.NET Identity的实现,我觉得我已经走到了最后一步,但就是无法让它工作。我想要做的就是在用户的当前会话(如果有)发生更改时使其无效,并将其发送回登录页面。从我今天阅读的几十篇与身份相关的文章中,我决定必须重写OnValidateIdentity委托,但它不起作用。下面是我的代码,如果有人能告诉我我错过了什么,我会非常感激,因为我肯定没有看到它 owinconformation.csC# ASP.NET标识2使标识无效困难,c#,asp.net-mvc,asp.net-mvc-5,ninject,asp.net-identity-2,C#,Asp.net Mvc,Asp.net Mvc 5,Ninject,Asp.net Identity 2,我今天一整天都在更新ASP.NET Identity的实现,我觉得我已经走到了最后一步,但就是无法让它工作。我想要做的就是在用户的当前会话(如果有)发生更改时使其无效,并将其发送回登录页面。从我今天阅读的几十篇与身份相关的文章中,我决定必须重写OnValidateIdentity委托,但它不起作用。下面是我的代码,如果有人能告诉我我错过了什么,我会非常感激,因为我肯定没有看到它 owinconformation.cs public static class OwinConfiguration {
public static class OwinConfiguration {
public static void Configuration(
IAppBuilder app) {
if (app == null) {
return;
}
// SOLUTION: the line below is needed so that OWIN can
// instance the UserManager<User, short>
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<UserManager<User, short>>());
// SOLUTION: which is then used here to invalidate
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/"),
ExpireTimeSpan = new TimeSpan(24, 0, 0),
Provider = new CookieAuthenticationProvider {
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<UserManager<User, short>, User, short>(
// SOLUTION: make sure this is set to 0 or it will take
// however long you've set it to before the session is
// invalidated which to me seems like a major security
// hole. I've seen examples set it to 30 minutes, in
// which time a disgruntled employee (say, after being
// fired) has plenty of opportunity to do damage in the
// system simply because their session wasn't expired
// even though they were disabled...
validateInterval: TimeSpan.FromMinutes(0),
regenerateIdentityCallback: (m, u) => u.GenerateUserIdentityAsync(m),
getUserIdCallback: (id) => short.Parse(id.GetUserId())
)
},
SlidingExpiration = true
});
}
}
internal static class UserExtensions {
public static async Task<ClaimsIdentity> GenerateUserIdentityAsync(
this User user,
UserManager<User, short> manager) {
var userIdentity = await manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
namespace X.Dependencies {
using System;
using System.Linq;
using System.Web;
using Data;
using Data.Models;
using Identity;
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Modules;
using Ninject.Web.Common;
using Services;
public static class NinjectConfiguration {
private static readonly Bootstrapper Bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start() {
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
Bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop() {
Bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel() {
var kernel = new StandardKernel();
try {
kernel.Bind<Func<IKernel>>().ToMethod(
c => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
} catch {
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(
IKernel kernel) {
if (kernel == null) {
return;
}
kernel.Bind<XContext>().ToSelf().InRequestScope();
kernel.Bind<IUserStore<User, short>>().To<UserStore>().InRequestScope();
kernel.Bind<IAuthenticationManager>().ToMethod(
c =>
HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
RegisterModules(kernel);
}
private static void RegisterModules(
IKernel kernel) {
var modules = AssemblyHelper.GetTypesInheriting<NinjectModule>().Select(Activator.CreateInstance).Cast<NinjectModule>();
kernel.Load(modules);
}
}
}
我有一种感觉,这与对UserManager
进行疯狂操作有关,但我似乎无法解决它。我认为OWIN应用程序必须为请求创建一个单例,但它没有发生,因此验证覆盖不起作用?问题是,我正在使用Ninject,我不知道如何让它与OWIN合作,因为OWIN在开发过程中要早得多。。。以下是Ninject配置:
NinjectConfiguration.cs
public static class OwinConfiguration {
public static void Configuration(
IAppBuilder app) {
if (app == null) {
return;
}
// SOLUTION: the line below is needed so that OWIN can
// instance the UserManager<User, short>
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<UserManager<User, short>>());
// SOLUTION: which is then used here to invalidate
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/"),
ExpireTimeSpan = new TimeSpan(24, 0, 0),
Provider = new CookieAuthenticationProvider {
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<UserManager<User, short>, User, short>(
// SOLUTION: make sure this is set to 0 or it will take
// however long you've set it to before the session is
// invalidated which to me seems like a major security
// hole. I've seen examples set it to 30 minutes, in
// which time a disgruntled employee (say, after being
// fired) has plenty of opportunity to do damage in the
// system simply because their session wasn't expired
// even though they were disabled...
validateInterval: TimeSpan.FromMinutes(0),
regenerateIdentityCallback: (m, u) => u.GenerateUserIdentityAsync(m),
getUserIdCallback: (id) => short.Parse(id.GetUserId())
)
},
SlidingExpiration = true
});
}
}
internal static class UserExtensions {
public static async Task<ClaimsIdentity> GenerateUserIdentityAsync(
this User user,
UserManager<User, short> manager) {
var userIdentity = await manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
namespace X.Dependencies {
using System;
using System.Linq;
using System.Web;
using Data;
using Data.Models;
using Identity;
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Modules;
using Ninject.Web.Common;
using Services;
public static class NinjectConfiguration {
private static readonly Bootstrapper Bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start() {
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
Bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop() {
Bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel() {
var kernel = new StandardKernel();
try {
kernel.Bind<Func<IKernel>>().ToMethod(
c => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
} catch {
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(
IKernel kernel) {
if (kernel == null) {
return;
}
kernel.Bind<XContext>().ToSelf().InRequestScope();
kernel.Bind<IUserStore<User, short>>().To<UserStore>().InRequestScope();
kernel.Bind<IAuthenticationManager>().ToMethod(
c =>
HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
RegisterModules(kernel);
}
private static void RegisterModules(
IKernel kernel) {
var modules = AssemblyHelper.GetTypesInheriting<NinjectModule>().Select(Activator.CreateInstance).Cast<NinjectModule>();
kernel.Load(modules);
}
}
}
namespace X.依赖项{
使用制度;
使用System.Linq;
使用System.Web;
使用数据;
使用数据模型;
使用身份;
使用Microsoft.AspNet.Identity;
使用Microsoft.Owin.Security;
使用Microsoft.Web.Infrastructure.DynamicModuleHelper;
使用Ninject;
使用Ninject.Modules;
使用Ninject.Web.Common;
使用服务;
公共静态类配置{
私有静态只读引导程序Bootstrapper=new Bootstrapper();
///
///启动应用程序
///
公共静态void Start(){
RegisterModule(typeof(OnePerRequestHttpModule));
RegisterModule(typeof(NinjectHttpModule));
初始化(CreateKernel);
}
///
///停止应用程序。
///
公共静态无效停止(){
Bootstrapper.ShutDown();
}
///
///创建将管理应用程序的内核。
///
///创建的内核。
私有静态IKernel CreateKernel(){
var kernel=新的标准内核();
试一试{
kernel.Bind().ToMethod(
c=>()=>新的引导程序().Kernel);
kernel.Bind().To();
注册服务(内核);
返回内核;
}抓住{
Dispose();
投掷;
}
}
///
///在这里加载您的模块或注册您的服务!
///
///内核。
私有静态无效注册服务(
IKernel内核){
if(内核==null){
返回;
}
kernel.Bind().ToSelf().InRequestScope();
kernel.Bind().To().InRequestScope();
kernel.Bind().ToMethod(
c=>
HttpContext.Current.GetOwinContext().Authentication).InRequestScope();
注册模块(内核);
}
专用静态无效注册表模块(
IKernel内核){
var modules=AssemblyHelper.GetTypesInheriting().Select(Activator.CreateInstance.Cast();
内核加载(模块);
}
}
}
很多OWIN和标识部分是通过复制/粘贴/调整我在网上找到的内容而组合在一起的。。。我真的很感谢你的帮助。提前谢谢 您的cookie设置为30分钟后过期,但SlidingExpiration设置为true。这意味着,如果用户未使用网站超过30分钟,cookie将在30分钟后过期。但是,如果用户停止使用该网站28分钟,然后在29分钟或30分钟过期时间内点击按钮,cookie过期时间将重置为另一个30分钟。实际上,cookie不会过期。您将看不到cookie过期的效果。cookie仅在30分钟后无效,会话将不再有效。如果cookie有效,则会话有效,反之亦然 这可能就是你正在经历的 设置为false
SlidingExpiration = false
您很可能缺少向OWIN注册的
UserManager
与最新VS一起提供的MVC模板具有以下代码行:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
这是你的电话号码。或者保留创建ApplicationUserManager
实例的静态方法
我有。还有一个DI容器的工作代码示例,它使用标识进行工作。我希望这能给你一些想法。一些代码会解释得更好。只有在您登录后才能访问此方法
[Authorise]
public ActionResult Dashboard()
{
return View();
}
您的身份验证cookie设置
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(2),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
SlidingExpiration = false
});
app.UseCookieAuthentication(新的CookieAuthenticationOptions
{
AuthenticationType=DefaultAuthenticationTypes.ApplicationOkie,
LoginPath=新路径字符串(“/Account/Login”),
Provider=新CookieAuthenticationProvider
{
OnValidateIdentity=SecurityStampValidator.OnValidateIdentity(
validateInterval:TimeSpan.FromMinutes(2),
regenerateIdentity:(管理器,用户)=>user.GenerateUserIdentityAsync(管理器))
},
slidengexpiration=false
});
这不正确。给定示例中的30分钟是将cookie与数据库中的值进行比较的频率。Cookie过期时间设置为24小时。抱歉,再次查看。现在是24小时。但我的解释是一样的。只要cookie未过期,会话就有效。我对SlidingExpiration的解释是一样的——只要网页上有用户活动,就会重置过期时间。所以cookie永远不会过期,会话也永远不会过期。ASP