ASP.NET身份2的Invalidate身份难点 [英] ASP.NET Identity 2 Invalidate Identity Difficulties

查看:193
本文介绍了ASP.NET身份2的Invalidate身份难点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经更新我的ASP.NET实现身份整天今天我觉得我的最后一步,但就是不能使它工作。所有我想要的发生是有用户当前会话(如果有的话)失效时,一些关于他们的变化和送他们回到登录页面。从数十种身份相关的文章我一直在阅读的今天,我已决定,我要覆盖OnValidateIdentity代表,但它只是不工作。下面是我的code,我真的AP preciate,如果有人可以告诉我,我错过了什么,因为我肯定我没有看到它...

I have been updating my implementation of ASP.NET Identity all day today and I feel I'm on the last step, but just can't make it work. All I want to happen is to have the user's current session (if any) invalidated when something about them changes and to send them back to the login page. From the dozens of Identity related articles I've been reading today, I've settled that I have to override the OnValidateIdentity delegate, but it's just not working. Below is my code, I would really appreciate it if someone could tell me what I'm missing because I surely am not seeing it...

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 方法看起来像它需要成为实体,这是我不喜欢的一部分,所以我做了一个extesion方法,它这是内部的装配与OWIN配置:

The GenerateUserIdentityAsync method looked like it needed to be a part of the entity, which I didn't like, so I made an extesion method for it that's internal to the assembly with the OWIN configuration:

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;
    }
}

我有一种感觉,它是与insancing的的UserManager&lt;使用者,短&GT; ,但我似乎无法来解决它。我认为OWIN应用程序有创建它的一个单独的请求,但它没有发生,从而验证覆盖不工作?关键是,我使用Ninject,我不知道如何使它与OWIN合作,因为OWIN是在管道早得多......这里的Ninject配置:

I have a feeling that it has something to do with insancing the UserManager<User, short>, but I can't seem to resolve it. I think the OWIN app has to create a singleton of it for the request, but it's not happening and thus the validation override isn't working? The thing is, I'm using Ninject, and I'm not sure how to make it cooperate with OWIN since OWIN is much earlier in the pipeline... Here's the Ninject configuration:

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与认同部分被复制/粘贴拼凑/从我在网上找到的调整......我真的AP preciate一些帮助。在此先感谢!

A lot of the OWIN and Identity portions were put together by copy/pasting/adjusting from what I've found online... I would really appreciate some help. Thanks in advance!

推荐答案

最有可能你缺少的UserManager 登记OWIN。

Most likely you are missing UserManager registration with OWIN.

与最新的VS给出的MVC模板有code的这些行:

The MVC template given with latest VS has these lines of code:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

这是在运行应用程序生命周期的早期,有效注册了如何创建 ApplicationUserManager 委托。这code通常只是坐在你的前行 app.UseCookieAuthentication 。并且需要提供OWIN上,因为它是在饼干无效的例程时 SecurityStamp ApplicationUserManager 委托C>在数据库中更改。

This is run very early in the application lifecycle and effectively registers the delegate on how to create ApplicationUserManager. This code usually sits just before your line app.UseCookieAuthentication. And it is required to provide OWIN with delegate on how to create ApplicationUserManager because it is used in the routine of cookie invalidation when SecurityStamp is changed in the database.

现在棘手的部分是给OWIN正确的委托进行工作。运行此code之后创建了很多倍的DI容器。所以,你要小心这一点。通常你需要注册您的DI为的ServiceProvider为MVC让你的控制器解决。而如果这个工程,你会得到你的 ApplicationUserManager 从MVC服务提供商:

Now the tricky part is to give OWIN correct delegate to work with. A lot of the times your DI container is created after this code is run. So you need to be careful about this. And usually you need to register your DI as a ServiceProvider for MVC to get your controllers resolved. And if this works, you'll get your ApplicationUserManager from MVC service provider:

app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());

下面是<一个href=\"https://github.com/trailmax/IoCIdentitySample/blob/Part1/IoCIdentity/App_Start/Startup.Auth.cs\"相对=nofollow>在code 的全样本。或者你保持一个创建 ApplicationUserManager 实例的静态方法。

Here is the full sample of the code. Or you keep the static method that creates an instance of the ApplicationUserManager.

我已经博客中使用DI与Identity 。而且还有一个 GitHub的库与DI容器工作的工作code样品与恒等式。我希望这可以给你一些想法。

I've blogged about using DI with Identity. And there is a GitHub repository with working code sample of DI container working with Indentity. I hope this can give you some ideas.

这篇关于ASP.NET身份2的Invalidate身份难点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆