我正在尝试设置项目结构,以便我有一个WebApi,WebUI和Domain层。我已将所有Asp.Net.Identity对象移动到Domain层中,并且也在此处设置了ApplicationContext(继承自IdentityContext)。
(我已经将本教程和软件包用作非常好的基础。http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/)
在WebAPI层中,我可以正确使用帐户控制器登录和注册。但是,我无法生成访问令牌。
OAuthGrantResourceOwnerCredentialsContext方法在内部使用
var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
这样工作正常,但并没有给我与我的帐户控制器相同的上下文,因为我在此使用Unity构造函数注入来使用域中的ApplicationUserManager。
我尝试过注入OAuth类,但我似乎从来没有得到实例。
有什么建议吗?
编辑,这是我在默认WebApi项目中的Startup类中所拥有的。
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
因此,在获取访问令牌时似乎使用了ApplicationOAuthProvider。
- 更多信息。
UnityConfig.cs
container.RegisterType<ApplicationDbContext>(); //this is referencing my domain layer
Startup.Auth.cs
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
ApplicationOAuthProvider.cs
注入构造函数如下
public class ApplicationOAuthProvider : OAuthAuthorizationServerProvider
{
private readonly string _publicClientId;
private ApplicationUserManager userManager;
public ApplicationOAuthProvider(ApplicationUserManager userManager)
{
this.userManager = userManager;
}
public ApplicationOAuthProvider(string publicClientId)
{
//this.userManager = userManager;
if (publicClientId == null)
{
throw new ArgumentNullException("publicClientId");
}
_publicClientId = publicClientId;
}
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
//var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>(); //PROBLEM LINE!!!
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
}
}
问题行如上所示。请求令牌时调用此方法,userManager始终为null。
编辑以显示UnityWebApiActivator.cs
public static class UnityWebApiActivator
{
/// <summary>Integrates Unity when the application starts.</summary>
public static void Start()
{
// Use UnityHierarchicalDependencyResolver if you want to use a new child container for each IHttpController resolution.
// var resolver = new UnityHierarchicalDependencyResolver(UnityConfig.GetConfiguredContainer());
var resolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
GlobalConfiguration.Configuration.DependencyResolver = resolver;
}
/// <summary>Disposes the Unity container when the application is shut down.</summary>
public static void Shutdown()
{
var container = UnityConfig.GetConfiguredContainer();
container.Dispose();
}
}
答案 0 :(得分:0)
我刚刚使用Identity创建了纯WebApi项目,检查了类并且不确定我是否正确理解了您的问题。
标准VS2013模板在Startup.Auth.cs
:
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// blah - other stuff
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
Provider = new ApplicationOAuthProvider(PublicClientId),
// another blah
};
app.UseOAuthBearerTokens(OAuthOptions);
//blah-blah-blah
}
}
我已经检查过,ApplicationOAuthProvider
在其他任何地方都没有使用过。所以不需要注射它。
正如你所说,在这个类的内部,它要求context.OwinContext.GetUserManager<ApplicationUserManager>()
获得用户管理器。如果在那里得到ApplicationDbContext
的错误实例,则会将不正确的ApplicationUserManager
实例注入到Owin上下文中。你还有这句话:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
用这个替换它:
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
这应该做的 - 这将是最好的解决方案。
或者在ApplicationOAuthProvider
替换行中,从OWIN上下文中获取ApplicationUserManager
:
var userManager = DependencyResolver.Current.GetService<ApplicationUserManager>()
这应该从Unity解析您的用户经理,为您提供正确的DbContext
。