通过ASP.NET Webforms,OWIN和ASP.NET Identity了解Autofac中间件的使用

时间:2016-10-25 07:24:10

标签: c# webforms owin autofac asp.net-identity-2

我目前正在更新使用MembershipProvider和RoleProvider的旧ASP.NET Webforms应用程序,以使用较新的ASP.NET Identity类。另外,我使用Autofac进行依赖注入,为了保持一致性,我希望能够将它与新的Identity类一起使用。

ASP.NET Identity现在依赖于OWIN中间件,我已经成功地通过添加以下Startup.cs类将OWIN中间件设置合并到我的应用程序中:

internal partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var builder = new ContainerBuilder();

        AutofacConfig.RegisterTypes(builder);
        AutofacConfig.RegisterIdentityTypes(builder, app);

        var container = builder.Build();
        Global.SetContainer(container);

        app.UseAutofacMiddleware(container);

        ConfigureAuth(app);
    }
}

我使用Autofac注册身份类,如下所示:

internal static class AutofacConfig
{      
    public static void RegisterIdentityTypes(ContainerBuilder builder, IAppBuilder app)
    {
        builder.RegisterType<ApplicationUserStore>().As<IUserStore<ApplicationUser>>().InstancePerRequest();
        builder.RegisterType<ApplicationUserManager>().AsSelf().InstancePerRequest();
        builder.RegisterType<ApplicationSignInManager>().AsSelf().InstancePerRequest();
        builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).InstancePerRequest();
        builder.Register(c => app.GetDataProtectionProvider()).InstancePerRequest();
    }
}

我可以看到当我导航到我的WebForms登录页面时,实例化了以下ApplicationSignInManager类,并且还解析了它的构造函数参数,以便向我建议Autofac正常工作。

public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    public ApplicationSignInManager(
        ApplicationUserManager userManager,
        IAuthenticationManager authenticationManager)
        : base(userManager, authenticationManager)
    {
        // userManager is valid
        // authenticationManager is valid
    }
}

当我单击WebForms登录页面上的登录按钮时,将调用以下方法,并通过Autofac属性注入实例化ApplicationSignInManager。然后调用正确的Identity类实现。

public partial class SignIn : BasePage
{
    // Autofac property injection 
    public ApplicationSignInManager ApplicationSignInManager { get; set; }

    ....

    protected void SignInClick(object sender, EventArgs e)
    {
        // Validate the user password
        var result = this.ApplicationSignInManager.PasswordSignIn(
            this.email.Text,
            this.password.Text,
            this.remember.Checked,
            true);

        ....
     }

所以一切似乎都很好,但对我来说似乎不对,我不知道OWIN和Autofac的连接位置,甚至是否需要。如果我从Startup.cs中删除以下行...

,为火灾添加燃料
    app.UseAutofacMiddleware(container);

......一切仍然有效!哪个不对,可以吗?

MVC的许多示例似乎都表明这是获取Identity对象的正确方法(通过GetOwinContext()调用):

    protected void SignInClick(object sender, EventArgs e)
    {
        var signInManager = this.Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

        // Validate the user password
        var result = signInManager.PasswordSignIn(
            this.email.Text,
            this.password.Text,
            this.remember.Checked,
            true);

        ....
    }

但是在执行该代码时,&#39; signInManager&#39;变量总是为NULL。

我真的需要这行代码吗?

 app.UseAutofacMiddleware(container);

有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:3)

Documentation表示

  

对于一个简单的场景,app.UseAutofacMiddleware(容器);将处理向OWIN请求范围添加Autofac生命周期以及将在Autofac中注册的中间件添加到管道中。

请参阅source进行确认。

基本上,如果您从Autofac向OWIN管道(即中间件)注入任何内容,则需要此行。但是对于你的场景,它看起来不像你做的那样,所以删除那一行不会改变任何东西。

至于从OWIN管道解析对象,你真的不需要这样做 - 你已经从Autofac解析了对象。但是,SecurityStampValidator仍会从OWIN中解析ApplicationUserManager,因此您仍需要将其注册到OWIN:

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

请参阅this question/answer背后的原因。

答案 1 :(得分:0)

我知道这对游戏来说已经很晚了,但我正在更新一个旧版应用程序,但我遇到了“IAppBuilder 不包含‘UseAutofacMiddleware’的定义” 错误并通过添加 NuGet 包 Autofac.Owin 修复它。