Intermittent ASP.NET oAuth issue with Google, AuthenticationManager.GetExternalIdentityAsync is returning null

醉酒当歌 提交于 2019-11-30 06:35:36

I got this problem yesterday and I was COMPLETELY STUCK ! And, as you described, I got it just like that with no reason.

I managed to fix it (after hours of comparing 2 projects - 1 test project that worked no problem every time and another that was a more serious project - and they had the exact same code, but different dll versions)

The problem was with the DLLs - the referenced packages from Nuget. Make sure you have the latest packages and also check the runtime section in your web.config.

After I updated all Owin related packages and Microsoft.Owin and added:

<assemblyBinding>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
  </dependentAssembly>
  <dependentAssembly>
    <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
  </dependentAssembly>
</assemblyBinding>

... it worked again ! They might vary based on your used packages, but that's how it worked for me.

Adamy

I forgot to enable "Google + API" in the google developer console. Google login appears to be fine, but GetExternalLoginInfoAsync returns null.

You can follow this link https://stackoverflow.com/a/27631109/657926

There is a bug in Microsoft's Owin implementation for System.Web. The one that is being used when running Owin applications on IIS. Which is what probably 99% of us do, if we're using the new Owin-based authentication handling with ASP.NET MVC5.

The bug makes cookies set by Owin mysteriously disappear on some occasions.

Put this nuget before https://github.com/KentorIT/owin-cookie-saver before app.UseGoogleAuthentication(...)

Tom I am using google-oauth in my asp.net application by using REST API. it is working fine and i am not facing any connection issues.

The following steps i am performing:

1.I have created one project in google developer console in that i have created settings "Client ID for web application" which will contains the following parameters.

a)Client ID => It will be automatically generated by google b)Email address=> It will be automatically generated by google c)Client secret=> It will be automatically generated by google d)Redirect URIs => Need to specify url of web page which will be used to handle authentication process. In this page we can authenticate and we can get user's basic information.

my url: "http://localhost:1822/WebForm1.aspx/code"

My Usage:

  1. I have created one sample project which will contains "Webpage1.aspx" and "Webpage2.aspx".

I have set "Webpage2.aspx" startup page and I am forming open auth url in the "Webpage2.aspx" and redirecting to google login page.

After login, it will redirect to "Webpage1.aspx" along with access code. By passing this access code to "https://accounts.google.com/o/oauth2/token" url, i am getting access token along with token type and token expiry time. After that by passing this access to the "https://www.googleapis.com/oauth2/v2/userinfo" url, i am getting user basic information like "email,Name, Gender, Photo, etc...)

Example Code

    public class GoogleAuthorizationData
    {
        public string access_token { get; set; }
        public int expires_in { get; set; }
        public string token_type { get; set; }

    }

  public class GoogleUserInfo
    {
        public string name { get; set; }
        public string family_name { get; set; }
        public string gender { get; set; }
        public string email { get; set; }
        public string given_name { get; set; }
        public string picture { get; set; }
        public string link { get; set; }
        public string id { get; set; }

    }

  Webpage1.aspx
  ============
 protected void Page_Load(object sender, EventArgs e)
        {
            string code = Request.QueryString["code"].ToString();
            string scope = Request.QueryString["scope"].ToString();
            string url = "https://accounts.google.com/o/oauth2/token";
            string postString = "code=" + code + "&client_id=" + ConfigurationManager.AppSettings["GoogleClientID"].ToString() + "&client_secret=" + ConfigurationManager.AppSettings["GoogleSecretKey"].ToString() + "&redirect_uri=" + ConfigurationManager.AppSettings["ResponseUrl"].ToString() + "&grant_type=authorization_code";

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url.ToString());
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            UTF8Encoding utfenc = new UTF8Encoding();
            byte[] bytes = utfenc.GetBytes(postString);
            Stream os = null;
            try
            {
                request.ContentLength = bytes.Length;
                os = request.GetRequestStream();
                os.Write(bytes, 0, bytes.Length);
            }
            catch
            { }

            try
            {
                HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
                Stream responseStream = webResponse.GetResponseStream();
                StreamReader responseStreamReader = new StreamReader(responseStream);
                var result = responseStreamReader.ReadToEnd();//
                var json = new JavaScriptSerializer();

                GoogleAuthorizationData authData = json.Deserialize<GoogleAuthorizationData>(result);

                HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create("https://www.googleapis.com/oauth2/v2/userinfo");
                request1.Method = "GET";
                request1.ContentLength = 0;
                request1.Headers.Add("Authorization", string.Format("{0} {1}", authData.token_type, authData.access_token));
                HttpWebResponse webResponse1 = (HttpWebResponse)request1.GetResponse();
                Stream responseStream1 = webResponse1.GetResponseStream();
                StreamReader responseStreamReader1 = new StreamReader(responseStream1);
                GoogleUserInfo userinfo = json.Deserialize<GoogleUserInfo>(responseStreamReader1.ReadToEnd());
               Response.Write(userinfo.email);

            }
            catch (Exception eX)
            {
                throw eX;
            }





        }

I believe you should't be using app.UseGoogleAuthentication(); as that's a call which will try to use OpenID 2.0, which has been deprecated.
What you should be using instead is OAuth 2.0 for Login (OpenID Connect).
So:

  1. register your app in Google Developers Console
  2. enable it to access Google+ API (even though you do not intend to use Google+ directly - it's now used as a mean of authentication)
  3. enable ASP.NET Identity's Google authentication this way
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()  
{  
    ClientId = "YOUR_CLIENT_ID",  
    ClientSecret = "YOUR_CLIENT_SECRET",  
});

I have the same problem. I am using Visual Studio 2013 and website is on Azure. The social log in that had been working without issue stopping working and LinkLoginCallback was receiving null in loginInfo. I republished the project without code change or rebuilding and then loginInfo received correct data and all works fine. Does not make sense but there you go.

Make sure that 3rd party cookies are enabled. I have found out that if you're not logged into google when you try to 'Register' a user with your application, it redirects to the login page as it looks for this cookie that isn't there, but still manages to do what it needs with the external provider. The next time you try to 'Register', because it's done part of the process it doesn't need to look for the external cookie anymore and so succeeds second time around.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!