自定义用户管理器在 OAuthAuthorizationServerProvider 中不可用



我正在WebApi系统中实现 ASP.Net Identity 2。为了管理新帐户的电子邮件确认,我必须创建一个自定义ApplicationUserManager并注册它,以便为每个请求创建它:

public class IdentityConfig{
    public static void Initialize(IAppBuilder app)
    {
        [snip]
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    }

它在 API 控制器中正常工作,如下所示:

public class AccountController : ApiController
{
    public ApplicationUserManager UserManager
    {
        get
        {
            return HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
    }

面临的问题是,在我尝试在 OAuth 令牌创建方法中访问 ApplicationUserManager.Create 方法之前

,没有调用它:
public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
{
    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var mgr = HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();

在上面的代码中,mgr 为 null,因为 GetUserManager 检索 null

令牌创建方法是否在管道的早期以某种方式调用CreatePerOwinContext方法?如果是这样,缓存ApplicationUserManager以便可以在GrantResourceOwnerCredentials内部使用它的最佳方法是什么?

这个很棘手。事实证明,启动代码必须按一定的顺序完成。

此代码将起作用。

public class IdentityConfig{
    public static void Initialize(IAppBuilder app)
    {   
        // correct... first create DB context, then user manager, then register  OAuth Provider
        app.CreatePerOwinContext(AuthContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
            Provider = new SimpleAuthorizationServerProvider()
        };
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
    }
}

如果更改向应用注册代码的顺序,可能会产生意想不到的后果。此代码导致应用程序用户管理器在令牌生成方法 GrantResourceOwnerCredentials 中为 null

// wrong... these two lines must be after the ApplicationUserManager.Create line
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
[snip]
app.CreatePerOwinContext(AuthContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

当我在做这件事时,还有一件事可能会绊倒某人。这些行会导致 AuthContext 在令牌生成方法 GrantResourceOwnerCredentials 中为 null

// wrong... The AuthContext must be instantiated before the ApplicationUserManager
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext(AuthContext.Create);
[snip]
app.UseOAuthAuthorizationServer(OAuthServerOptions);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

不要在GrantResourceOwnerCredentials中使用HttpContext.Current.GetOwinContext(),因为您已经有上下文:(OAuthGrantResourceOwnerCredentialsContext context)

而是这样做:

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

为每个请求创建CreatePerOwinContext,因此您应该能够ApplicationUserManager获取对象。它应该立即调用,在 Startup .也许您的启动实现不正确。我在这里写了一个答案,其中包含一些实现的细节。

当向 OwinContext 询问 ApplicationUserManager 时,如果 app.UseWebApi(config);行在 Oauth 设置之前。

下面将导致大多数调用HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>();

以返回空值。

        HttpConfiguration config = new HttpConfiguration();
        WebApiConfig.Register(config);
        app.UseWebApi(config); <-- Bad location
        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = new ApplicationOAuthProvider("clientId"),
            RefreshTokenProvider = new SimpleRefreshTokenProvider()
        };
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseOAuthBearerTokens(OAuthOptions);

app.UseWebApi(config);移动到应用下方。UseOAuth 方法将允许您从 OwinContext 获取 ApplicationUserManager。

这对我有用:

        HttpConfiguration config = new HttpConfiguration();
        WebApiConfig.Register(config);
        OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString("/token"),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = new ApplicationOAuthProvider("clientId"),
            RefreshTokenProvider = new SimpleRefreshTokenProvider()
        };
        app.UseOAuthAuthorizationServer(OAuthServerOptions);
        app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        app.UseOAuthBearerTokens(OAuthOptions);
        app.UseWebApi(config); // <- Moved

相关内容

  • 没有找到相关文章

最新更新