IOwinContext.Get <dbcontext>()返回null

时间:2016-04-26 21:15:55

标签: c# asp.net-mvc entity-framework asp.net-web-api owin

我正在尝试添加身份验证以向我从空项目启动的现有MVC 5应用程序添加身份验证。我启动了一个包含单个用户帐户的新WebAPI项目,因此我可以看到它是如何配置的。我复制了与身份验证有关的代码并重构了名称空间和类名。在下面的代码中,第一行var identityContext = context.Get<IdentityDbContext>()返回null并导致第二行var userStore = new UserStore<AdminAppUser>(identityContext)由于null参数而引发错误。

我可能没有包含足够的代码,因为我对MVC身份验证非常陌生并且对所有部分如何组合在一起时理解不足。如果我需要包含更多代码,请告诉我哪些部分会有用。谢谢!

public static AdminAppUserManager Create(IdentityFactoryOptions<AdminAppUserManager> options, IOwinContext context)
    {

        var identityContext = context.Get<IdentityDbContext>();
        var userStore = new UserStore<AdminAppUser>(identityContext);

        var manager = new AdminAppUserManager(userStore);
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<AdminAppUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };
        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<AdminAppUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }

修改

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)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(AdminAppIdentityDbContext.Create);
        app.CreatePerOwinContext<AdminAppUserManager>(AdminAppUserManager.Create);

        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        app.UseCookieAuthentication(new CookieAuthenticationOptions());
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

        // 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),
            // In production mode set AllowInsecureHttp = false
            AllowInsecureHttp = true
        };

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);

        // Uncomment the following lines to enable logging in with third party login providers
        //app.UseMicrosoftAccountAuthentication(
        //    clientId: "",
        //    clientSecret: "");

        //app.UseTwitterAuthentication(
        //    consumerKey: "",
        //    consumerSecret: "");

        //app.UseFacebookAuthentication(
        //    appId: "",
        //    appSecret: "");

        //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
        //{
        //    ClientId = "",
        //    ClientSecret = ""
        //});
    }
}

startup.cs:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }
}

编辑2:

public class AdminAppIdentityDbContext : IdentityDbContext<AdminAppUser>
{
    public AdminAppIdentityDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static AdminAppIdentityDbContext Create()
    {
        return new AdminAppIdentityDbContext();
    }
}

2 个答案:

答案 0 :(得分:0)

应该有一些在启动时调用的ConfigureAuth方法,以确定每个Owin上下文有一个IdentityDbContext。该电话会看起来像:

app.CreatePerOwinContext(IdentityDbContext.Create);

该调用应该在VS为您自动生成的样板中。

答案 1 :(得分:0)

你也可以替换 var identityContext = context.Get<IdentityDbContext> var identityContext = new AdminAppIdentityDbContext();, 这并不重要。它可以节省你的时间。