Asp.net 身份,生成 WebApi 令牌 OAuthGrantResourceOwnerCredentialsCo



我正在尝试设置一个项目结构,以便我有一个WebApi,WebUI和域层。我已经将所有Asp.Net.Identity对象移动到域层,并且还在这里设置了ApplicationContext(继承自IdentityContext)。

(我使用本教程和软件包作为基础,非常好 http://tech.trailmax.info/2014/09/aspnet-identity-and-ioc-container-registration/。

在WebAPI层中,我能够正确使用帐户控制器进行登录和注册。但是,我无法生成访问令牌。

OAuthGrantResourceOwnerCredentialsContext 方法在内部使用

var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();

这工作正常,但不能为我提供与我的帐户控制器相同的上下文,因为我在其中使用 Unity 构造函数注入来使用域中的应用程序用户管理器。

我尝试注入 OAuth 类,但我似乎从未恢复实例。

有什么建议吗?


编辑,这是我在默认 WebApi 项目的启动类中拥有的内容。

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

因此,在获取访问令牌时似乎使用了应用程序OAuth提供程序。

--更多信息。

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

问题行如上所示。此方法在请求令牌时被调用,并且用户管理器始终为 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();
    }
}

我刚刚使用 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

相关内容

  • 没有找到相关文章