use*_*333 6 dependency-injection inversion-of-control autofac asp.net-web-api asp.net-identity-2
我正在使用ASP.Net Identity并希望ApplicationUserManager
通过以下文章将服务添加到我的所有自定义控制器:如何将我的Autofac容器插入ASP.NET Identity 2.1
这在我的控制器中完美运行,但是当我尝试通过在我的API上调用localhost:xxxx/token来创建令牌时.下面是调用的方法,但context.OwinContext.GetUserManager
返回null.
我曾尝试注入ApplicationUserManager
到ApplicationOAuthProvider
,但未能成功.你能指点我正确的方向吗?
编辑:10/15
好的,所以我已经进一步了,但我仍然卡住了.我能够使用以下内容初始化类:
var x = new DatabaseContext();
var store = new UserStore<ApplicationUser>(x);
var options = new IdentityFactoryOptions<ApplicationUserManager>()
{
DataProtectionProvider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("ApplicationName")
};
builder.Register<DatabaseContext>(c => x);
builder.Register<UserStore<ApplicationUser>>(c => store).AsImplementedInterfaces();
builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => options);
builder.RegisterType<ApplicationUserManager>();
builder.Register<ApplicationOAuthProvider>(c => new ApplicationOAuthProvider("self", new ApplicationUserManager(store, options))).As<IOAuthAuthorizationServerProvider>();
Run Code Online (Sandbox Code Playgroud)
这让我可以把它传递给ApplicationUserManager
我ApplicationOAuthProvider
的构造函数.在Startup.Auth
配置中,我使用以下内容初始化Provider:
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = (IOAuthAuthorizationServerProvider)GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider)),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
Run Code Online (Sandbox Code Playgroud)
这让我更接近解决方案,但仍有两个问题.
第一种是当我在API上调用/ token时userManager.FindAsync(context.UserName, context.Password)
返回null值,但userManager.FindByEmailAsync(context.UserName)
返回正确的用户.我最初的想法是密码错误,但我确定它与我注册的密码相同.
第二个问题,如果我在我的AccountController上调用register,然后调用/ token,我得到一个无法访问已处置的对象.对象名称:'UserStore'错误.所以我认为这意味着我没有ApplicationOAuthProvider
在我的Bootstrapper文件中正确初始化.
任何指导将不胜感激.谢谢!
我终于找到了解决方案\n第一个解决方案: \n第一个:更改你的bootstrap autofac类\n你应该添加singleInstance(); 避免每个请求依赖项错误[没有与 \xe2\x80\x98AutofacWebRequest\xe2\x80\x99 匹配的标签的范围]
\n\n\n\n builder.RegisterType<DatabaseContext>().AsSelf().SingleInstance();\n builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => new IdentityFactoryOptions<ApplicationUserManager>() { DataProtectionProvider = new DpapiDataProtectionProvider("your app name") });\n builder.RegisterType<ApplicationUserManager>().AsSelf().SingleInstance();\n // to resolve applicationUserManager \n builder.Register(c=>new ApplicationOAuthProvider(c.Resolve<ApplicationUserManager>())).AsImplementedInterfaces().SingleInstance();\n builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<DatabaseContext>())).AsImplementedInterfaces().SingleInstance();\n builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();\n
Run Code Online (Sandbox Code Playgroud)\n\n第二:在 Startup.cs\n 中,将删除 GlobalConfiguration.configuration.DependencyResolver 因为它总是给出 null ..所以我将使用 autofac 容器解析器,但应该从 lifescope 使用它,这个容器从引导 autofac 配置方法返回
\n\nOAuthOptions = new OAuthAuthorizationServerOptions\n {\n TokenEndpointPath = new PathString("/Token"),\n Provider = container.BeginLifetimeScope().Resolve<IOAuthAuthorizationServerProvider>(),\n AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),\n AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),\n AllowInsecureHttp = true\n };\n
Run Code Online (Sandbox Code Playgroud)\n\n第三:在您的ApplicationOAuthProvider类中将添加构造函数,以 applicationUserManager 作为参数
\n\n这修复了我两天谷歌搜索后的空错误,但找不到答案,希望它有帮助。
\n\n第二种解决方案:因为SingleInstance()不适合企业应用程序,所以您可以使用InstancePerRequest();对于所有寄存器类型
\n\n builder.RegisterType<DatabaseContext>().AsSelf().InstancePerRequest();\n builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => new IdentityFactoryOptions<ApplicationUserManager>() { DataProtectionProvider = new DpapiDataProtectionProvider("your app name") });\n builder.RegisterType<ApplicationUserManager>().AsSelf().InstancePerRequest();\n // to resolve applicationUserManager \n builder.Register(c=>new ApplicationOAuthProvider(c.Resolve<ApplicationUserManager>())).AsImplementedInterfaces().InstancePerRequest();\n builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<DatabaseContext>())).AsImplementedInterfaces().InstancePerRequest();\n builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();\n
Run Code Online (Sandbox Code Playgroud)\n\n在 Startup.cs 中
\n\n OAuthOptions = new OAuthAuthorizationServerOptions\n {\n TokenEndpointPath = new PathString("/Token"),\n // will instantiate new one to avoid Single Instance for resolving\n Provider = new CustomOAuthProvider(new ApplicationUserManager(new UserStore<Entities.ApplicationUser>(new DataContext()),\n AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),\n AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),\n AllowInsecureHttp = true\n };\n
Run Code Online (Sandbox Code Playgroud)\n\nCustomOAuthProvider 类
\n\nusing Microsoft.AspNet.Identity.Owin;\nusing Microsoft.Owin.Security;\nusing Microsoft.Owin.Security.OAuth;\nusing System.Security.Claims;\nusing System.Threading.Tasks;\n\npublic class CustomOAuthProvider:OAuthAuthorizationServerProvider\n{\n private ApplicationUserManager _appUserManager;\n public CustomOAuthProvider(ApplicationUserManager appUserManager)\n {\n this._appUserManager = appUserManager;\n }\n\n\n\n public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)\n {\n var allowedOrigin = "*";\n\n context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });\n\n\n var userManager = new ApplicationUserManager(new Microsoft.AspNet.Identity.EntityFramework.UserStore<AppUser>(new Data.DataContext()),new IdentityFactoryOptions<ApplicationUserManager>(),new Data.Repositories.SettingRepository(new Data.Infrastructure.DbFactory()));\n\n AppUser user = await userManager.FindAsync(context.UserName, context.Password);\n\n if (user == null)\n {\n context.SetError("invalid_grant", "Invalid username or password.");\n return;\n }\n if (!user.IsActive)\n {\n context.SetError("invalid_activation", "Inactive account, contact support.");\n return;\n }\n\n if (!user.EmailConfirmed)\n {\n context.SetError("invalid_grant", "User did not confirm email.");\n return;\n }\n\n\n ClaimsIdentity oAuthIdentity = await userManager.GenerateUserIdentityAsync(user, "JWT");\n\n AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, null);\n context.Validated(ticket);\n\n }\n\n\n public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)\n {\n if (context.ClientId == null)\n {\n context.Validated();\n\n }\n\n return Task.FromResult<object>(null);\n }\n\n\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
3523 次 |
最近记录: |