gpt4 book ai didi

asp.net-web-api - 使用 Autofac 和 ASP.Net Identity 将 ApplicationUserManager 传递给 ApplicationOAuthProvider

转载 作者:行者123 更新时间:2023-12-03 02:33:26 25 4
gpt4 key购买 nike

我正在使用 ASP.Net Identity,并希望按照本文将 ApplicationUserManager 服务添加到我的所有自定义 Controller :How to plug my Autofac container into ASP. NET Identity 2.1

这在我的 Controller 中工作得很好,但当我尝试通过在 API 上调用 localhost:xxxx/token 来创建 token 时就不行了。下面是调用的方法,但是 context.OwinContext.GetUserManager 返回 null。

我尝试将 ApplicationUserManager 注入(inject) 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>();

这允许我将 ApplicationUserManager 传递到我的 ApplicationOAuthProvider 的构造函数中。在 Startup.Auth 配置中,我使用以下内容初始化提供程序:

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

这让我更接近解决方案,但仍然存在两个问题。

第一个是当我在 API 上调用/token 时,userManager.FindAsync(context.UserName, context.Password) 返回 null 值,但 userManager.FindByEmailAsync(context.UserName ) 返回正确的用户。我最初的想法是密码错误,但我确定它与我注册时使用的密码相同。

第二个问题是,如果我在 AccountController 上调用 register,然后调用/token,我会收到 无法访问已处置的对象。对象名称:'UserStore' 错误。所以我认为这意味着我没有在 Bootstrapper 文件中正确初始化 ApplicationOAuthProvider

任何指导将不胜感激。谢谢!

最佳答案

终于找到解决办法了第一个解决方案:第一:更改 Bootstrap autofac 类你应该添加 singleInstance();避免每个请求依赖项错误[No Scope with a Tag Matching ‘AutofacWebRequest’]

   builder.RegisterType<DatabaseContext>().AsSelf().SingleInstance();
builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => new IdentityFactoryOptions<ApplicationUserManager>() { DataProtectionProvider = new DpapiDataProtectionProvider("your app name") });
builder.RegisterType<ApplicationUserManager>().AsSelf().SingleInstance();
// to resolve applicationUserManager
builder.Register(c=>new ApplicationOAuthProvider(c.Resolve<ApplicationUserManager>())).AsImplementedInterfaces().SingleInstance();
builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<DatabaseContext>())).AsImplementedInterfaces().SingleInstance();
builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();

第二个:在 Startup.cs 中将删除 GlobalConfiguration.configuration.DependencyResolver 因为它总是给 null ..所以我将使用 autofac 容器解析器但应该从生命周期范围使用它,这个容器从引导 autofac 配置方法返回

OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = container.BeginLifetimeScope().Resolve<IOAuthAuthorizationServerProvider>(),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};

第三:在您的 ApplicationOAuthProvider 类中将添加以 applicationUserManager 作为参数的构造函数

这修复了我在谷歌搜索两天后找不到答案的空错误,希望它有所帮助。

第二个解决方案:因为 SingleInstance() 不适合企业应用程序,因此您可以对所有 registerType 使用 InstancePerRequest();

   builder.RegisterType<DatabaseContext>().AsSelf().InstancePerRequest();
builder.Register<IdentityFactoryOptions<ApplicationUserManager>>(c => new IdentityFactoryOptions<ApplicationUserManager>() { DataProtectionProvider = new DpapiDataProtectionProvider("your app name") });
builder.RegisterType<ApplicationUserManager>().AsSelf().InstancePerRequest();
// to resolve applicationUserManager
builder.Register(c=>new ApplicationOAuthProvider(c.Resolve<ApplicationUserManager>())).AsImplementedInterfaces().InstancePerRequest();
builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<DatabaseContext>())).AsImplementedInterfaces().InstancePerRequest();
builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();

在 Startup.cs 中

 OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
// will instantiate new one to avoid Single Instance for resolving
Provider = new CustomOAuthProvider(new ApplicationUserManager(new UserStore<Entities.ApplicationUser>(new DataContext()),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};

CustomOAuthProvider 类

using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;
using System.Threading.Tasks;

public class CustomOAuthProvider:OAuthAuthorizationServerProvider
{
private ApplicationUserManager _appUserManager;
public CustomOAuthProvider(ApplicationUserManager appUserManager)
{
this._appUserManager = appUserManager;
}



public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var allowedOrigin = "*";

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });


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()));

AppUser user = await userManager.FindAsync(context.UserName, context.Password);

if (user == null)
{
context.SetError("invalid_grant", "Invalid username or password.");
return;
}
if (!user.IsActive)
{
context.SetError("invalid_activation", "Inactive account, contact support.");
return;
}

if (!user.EmailConfirmed)
{
context.SetError("invalid_grant", "User did not confirm email.");
return;
}


ClaimsIdentity oAuthIdentity = await userManager.GenerateUserIdentityAsync(user, "JWT");

AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, null);
context.Validated(ticket);

}


public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
if (context.ClientId == null)
{
context.Validated();

}

return Task.FromResult<object>(null);
}



}

关于asp.net-web-api - 使用 Autofac 和 ASP.Net Identity 将 ApplicationUserManager 传递给 ApplicationOAuthProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26371214/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com