我目前正在更新使用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);
有人能指出我正确的方向吗?
答案 0 :(得分:3)
对于一个简单的场景,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 修复它。