【问题标题】:AutoFac with ASP.Identity带有 ASP.Identity 的 AutoFac
【发布时间】:2014-08-09 14:52:13
【问题描述】:

我将 AutoFac 3.5 与 WebApi Integration 3.3 和 Asp.Identity 2.0.1 结合使用。问题是当我将 MyDbContext 指定为 InstancePerRequest 时,Asp.Net 身份存在问题。然后我得到了这种错误信息:

从请求实例的范围中看不到带有与“AutofacWebRequest”匹配的标记的范围。这通常表明注册为 per-HTTP 请求的组件正在由 SingleInstance() 组件(或类似场景)请求。在 Web 集成下,始终从 DependencyResolver.Current 或 ILifetimeScopeProvider.RequestLifetime 请求依赖项,而不是从容器本身.

我正在像这样注册 Asp 令牌提供程序:

public partial class Startup
{
    static Startup()
    {
        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/token"),
            RefreshTokenProvider = (IAuthenticationTokenProvider)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IAuthenticationTokenProvider)),
            Provider = (IOAuthAuthorizationServerProvider)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider)),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromHours(1),
            AllowInsecureHttp = true
        };
    }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseOAuthBearerTokens(OAuthOptions);
    }
}

AutoFac 部分如下所示:

builder.RegisterType<MyDbContext>().As<DbContext>().InstancePerRequest();
builder.RegisterType<SimpleRefreshToken>().As<IAuthenticationTokenProvider>();
builder.Register(x => new ApplicationOAuthProvider(
                        "self",
                        x.Resolve<Func<UserManager<User>>>()).As<IOAuthAuthorizationServerProvider>();

有人解决了这个问题吗?我找到了这个旧帖子ASP.net Identity, IoC and sharing DbContext

编辑

还有这篇博客文章,其中包含一个凌乱的解决方法http://blogs.msdn.com/b/webdev/archive/2014/02/12/per-request-lifetime-management-for-usermanager-class-in-asp-net-identity.aspx

【问题讨论】:

    标签: asp.net asp.net-web-api autofac asp.net-identity


    【解决方案1】:

    我能够通过从 OwinContext 中获取 AutofacWebRequest 并解析 UserManager 来解决问题。

    IOwinContext 被传递给每个 OwinMiddleware 的 Invoke 方法。在里面您可以找到作为 IDictionary 的 Enviroment 属性,其中包含大量信息,包括“autofac:OwinLifetimeScope”。 你可以得到这个 LifetimeScope,它应该用标签“AutofacWebRequest”指定,因为它是为每个 http 请求创建的嵌套 Scope,并解析你需要的对象类型。

    我的实现看起来与此类似。注意我在 UserManagerFactory 中生成 UserManager 类的方式。

    public class Startup
    {
        static Startup()
        {
            PublicClientId = "self";
    
            UserManagerFactory = () =>
            {
                //get current Http request Context
                var owinContext = HttpContext.Current.Request.GetOwinContext();
    
                //get OwinLifetimeScope, in this case will be "AutofacWebRequest"
                var requestScope = owinContext.Environment.ContainsKey("autofac:OwinLifetimeScope");
    
                if (!owinContext.Environment.Any(a => a.Key == "autofac:OwinLifetimeScope" && a.Value != null))
                    throw new Exception("RequestScope cannot be null...");
    
                Autofac.Core.Lifetime.LifetimeScope scope = owinContext.Environment.FirstOrDefault(f => f.Key == "autofac:OwinLifetimeScope").Value as Autofac.Core.Lifetime.LifetimeScope;
    
                return scope.GetService(typeof(UserManager<Models.UserModel>)) as UserManager<Models.UserModel>;
    
            };
    
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProviderCustom(PublicClientId, UserManagerFactory),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                AllowInsecureHttp = true
            };
        }
    
        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
    
        public static Func<UserManager<Models.UserModel>> UserManagerFactory { get; set; }
    
        public static string PublicClientId { get; private set; }
    
        public void Configuration(IAppBuilder app)
        {
    
            var builder = new ContainerBuilder();
    
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
    
            builder.RegisterType<UserModelsConvert>().InstancePerApiRequest();
            builder.RegisterType<UserStoreCustom>().As<IUserStore<Models.UserModel>>().InstancePerApiRequest();
            builder.RegisterType<UserManager<Models.UserModel>>().InstancePerApiRequest();
    
            //loading other projects
            builder.RegisterModule(new LogicModule());
    
            var container = builder.Build();
    
            app.UseAutofacMiddleware(container);
    
            //// Create the depenedency resolver.
            var resolver = new AutofacWebApiDependencyResolver(container);
    
            // Configure Web API with the dependency resolver
            GlobalConfiguration.Configuration.DependencyResolver = resolver;
    
            app.UseOAuthBearerTokens(OAuthOptions);
    
            //extend lifetime scope to Web API
            app.UseAutofacWebApi(GlobalConfiguration.Configuration);
    
            //app.UseWebApi(config);
    
        }
    }
    

    我希望这会有所帮助。如果遗漏了什么,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多