C#-ASP.NET Identity 2使身份困难失效
作者:互联网
我今天整天都在更新我的ASP.NET Identity实施,我觉得自己已经走到最后一步,但无法使其正常工作.我要做的就是在用户的当前会话(如果有的话)发生变化时使该会话无效,然后将其发送回登录页面.从我今天阅读的数十篇有关Identity的文章中,我已经解决了我必须重写OnValidateIdentity委托的问题,但是这是行不通的.以下是我的代码,如果有人可以告诉我我所缺少的内容,因为我肯定没有看到它,我将非常感激…
OwinConfiguration.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
});
}
}
GenerateUserIdentityAsync方法看起来像是实体的一部分,我不喜欢它,因此我为它创建了一个extestion方法,该方法在OWIN配置的程序集内部:
UserExtensions.cs
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;
}
}
我感觉这与增加UserManager< User,short>有关,但是我似乎无法解决.我认为OWIN应用必须为请求创建一个单例,但是没有发生,因此验证覆盖无效吗?事情是,我正在使用Ninject,但由于OWIN的开发流程还很早,所以我不确定如何使其与OWIN合作……这是Ninject配置:
NinjectConfiguration.cs
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);
}
}
}
通过从网上找到的内容进行复制/粘贴/调整,将OWIN和Identity的许多部分组合在一起……我非常感谢您的帮助.提前致谢!
解决方法:
您很可能缺少在OWIN中注册的UserManager.
最新VS提供的MVC模板具有以下代码行:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
它在应用程序生命周期的早期运行,并有效地注册了有关如何创建ApplicationUserManager的委托.此代码通常位于您的线路应用程序UseCookieAuthentication之前.并且需要向OWIN提供有关如何创建ApplicationUserManager的委托,因为在数据库中更改SecurityStamp时,它将在cookie无效的例程中使用.
现在,棘手的部分是给OWIN正确的委托进行工作.很多情况下,运行此代码后会创建DI容器.因此,您需要注意这一点.通常,您需要将DI注册为MVC的服务提供商,才能解决控制器问题.如果可行,您将从MVC服务提供商处获取ApplicationUserManager:
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
这是full sample of the code.或者保留创建ApplicationUserManager实例的静态方法.
我有blogged about using DI with Identity.还有一个带有Indentity的DI容器工作代码示例的GitHub repository.我希望这可以给您一些想法.
标签:asp-net-mvc-5,ninject,asp-net-identity-2,c,asp-net-mvc 来源: https://codeday.me/bug/20191027/1945949.html