SigninManager.ExternalSigninAsync上的.Net空指针

时间:2016-04-20 18:47:41

标签: .net google-signin

我试图通过Google将用户登录到我的网站,并且谷歌登录部分正在运行。但是,当我从Google收到用户信息并将其转到我的帐户控制器时,我收到以下错误:

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

Source Error: 


Line 336:            System.Diagnostics.Debug.WriteLine("loginInfo = " + loginInfo);
Line 337:            // Sign in the user with this external login provider if the user already has a login
Line 338:            var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
Line 339:            switch (result)
Line 340:            {

我想弄清楚的是,这是什么东西是空的。它不是loginInfo,因为该行中的调试器通知我:

loginInfo = Microsoft.AspNet.Identity.Owin.ExternalLoginInfo

它也不是SignInManager,因为在没有空指针错误之前,它在整个程序中多次使用。并且result是分配的新变量,因此也不能为空。导致此错误的原因是什么?

我的整个ExternalLoginCallback方法如下所示,尽管它是Google自动生成的方法。

   //
    // GET: /Account/ExternalLoginCallback
    [AllowAnonymous]
    public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
    {
        var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (loginInfo == null)
        {
            return RedirectToAction("Login");
        }
        System.Diagnostics.Debug.WriteLine("loginInfo = " + loginInfo);
        // Sign in the user with this external login provider if the user already has a login
        var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
        switch (result)
        {
            case SignInStatus.Success:
                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = false });
            case SignInStatus.Failure:
            default:
                // If the user does not have an account, then prompt the user to create an account
                ViewBag.ReturnUrl = returnUrl;
                ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
                return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
        }
    }

请注意,其他有类似问题的人会因为他们的Google+ API没有开启而受到影响,但事实并非如此。这是我打开的apis:

BigQuery API    Disable 
Debuglet Controller API     Disable 
Google Cloud SQL    Disable 
Google Cloud Storage    Disable 
Google Cloud Storage JSON API   Disable 
Google+ API     Disable 
Tasks API   Disable 
YouTube Data API v3     Disable 

更新:有人建议loginInfo的其中一个属性可能为null,但情况并非如此。我扩展了debug语句以列出loginInfo的所有属性,并得到以下信息:

loginInfo email = <firstname>.<lastname>@<organization>.org
 external identity = System.Security.Claims.ClaimsIdentity
 login = Microsoft.AspNet.Identity.UserLoginInfo
 Default user name FirstLast

更新2 深入了解loginInfo的属性后,我了解到ExternalIdentity.Actor属性为null,所以我认为这是问题所在,但我仍然没有这样做。我知道为什么。

更新3 我不认为Actor是空的是问题,因为我尝试使用不同的项目进行调试,其中google登录正常工作并且它也在那里为空。所以我仍然不知道发生了什么。

以下是loginInfo的所有属性:

loginInfo email = jim.stewart@thelangschool.org
 externalidentity.actor = 
 externalidentity.claims = System.Security.Claims.ClaimsIdentity+<get_Claims>d__0
 externalidentity.bootstrapcontext = 
 authenticationtype = ExternalCookie
 loginprovider = Google
 loginkey = 103852334887708800511
 Default user name JimStewart

1 个答案:

答案 0 :(得分:1)

我明白了。 loginInfo并不是空的,它是SignInManager。我从来没有在我的Startup.auth.cs中创建它。如果您遇到此问题,请打开该文件并找到ConfigureAuth方法并添加以下行:

app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

这实际上与此问题中的答案相同:ApplicationSignInManager class is null during authentication process。对于复制品感到抱歉;在我之前寻找答案时,我没有找到这个。