OWIN GetExternalLoginInfoAsync always returns null

I created a new MVC5 web application, and when I try to log in using Google or Facebook, the ExternalLoginCallback action is called in the AccountController , but GetExternalLoginInfoAsync() always returns null:

 var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); if (loginInfo == null) { return RedirectToAction("Login"); } 

Since it is always zero, it simply redirects back to the login page, and the process begins. How can i fix this?

+64
c # asp.net-mvc owin google-openid
Nov 04 '13 at 19:18
source share
16 answers

To enable Google OWIN to work properly on the standard Visual Studio 2013 site, ASP.Net MVC5, I had to:

  1. Set up your Google OpenId account at https://console.developers.google.com/project.

  2. Set the callback url to blah/signin-google .
    Important notes on what you do not need to do:

    • You do not need to use HTTPS for Google to redirect back; You can even redirect back to regular http: // localhost , no problem.

    • You do not need to configure anything for the redirect URL — no routes, controller actions, or special permissions in Web.Config. The redirect URL is always / signin-google, and OWIN deals with this behind the scenes.

For example, if your site was me.com, you could have these 3 callback URLs in the Google Developer Console:

 http://localhost:53859/signin-google http://test.me.com/signin-google https://me.com/signin-google 

The first, including the port number that VS gave you for your project.

  1. Enable the Google+ API . This is one hidden &error=access_denied and is the main cause of the problem in this question - if you do not, it is easy to miss that the Request to /account/ExternalLoginCallback includes &error=access_denied , and this is because Google said no to OWIN request for the main Google+ user profile. I can’t say whose fault it is, Google or Microsoft.

To enable the Google+ API in the developer’s console, click the API on the left, find Google+, click it and click "Enable." Yes, you really need to do this. They are waiting for you if you do not.

  1. Add the ClientId and ClientSecret that Google gave you in the developer console to Startup.Auth, but improve the code in the process to explicitly use OAuth2 and explicitly request the user's email address:

     var google = new GoogleOAuth2AuthenticationOptions() { ClientId = "123abc.apps.googleusercontent.com", ClientSecret = "456xyz", Provider = new GoogleOAuth2AuthenticationProvider() }; google.Scope.Add("email"); app.UseGoogleAuthentication(google); 

It. It finally made it work.

I just want to repeat again, there are many answers to this issue and such questions as when OWIN / Google does not work, and almost all of them do not correspond to the current VS2013 / MVC5 / OWIN template.
You do not need to modify Web.Config at all.
You do not need to create any special routes at all.
You should not try to point /signin-google to another location or use a different callback URL, and you should definitely not try to bind it directly to /account/externallogincallback or externalloginconfirmation , because they are both separate from /signin-google and necessary steps in the OWIN / Google process.

+98
Apr 28 '15 at 13:50
source share

Ok, I found out why this is null. You must enable the Google + API in the Google console. Also, make sure the secret key does not concatenate with a space at the end after you insert it into your code. Why can't they return a normal error? I dont know.

+46
Dec 21 '14 at 1:03
source share

It seems that the Nuget package Microsoft.Owin.Security.Facebook version 3.0.1 no longer works with Facebook login.

Update this package to version 3.1.0 before release, you can use the following:

Microsoft.Owin.Security.Facebook -Pre installation package

+19
Mar 29 '17 at 18:56
source share

As others correctly said, most of the time, because you do not have rights to the Google+ API, here's how to get permission for a project in the Google API Manager on the Google+ API

Step 1. Select "Project" from the top list with a list and go to "Control Panel"> "Enable API". enter image description here

Step 2: Find Google Plus and select it. enter image description here

Step 3: Turn It On ! enter image description here

if you return to the control panel for this project, you can see the list of allowed APIs for this project below enter image description here

+7
Aug 6 '16 at 15:10
source share

I know this is stupid, but after a long struggle restarting IIS solved the problem for me.

+3
Feb 08 '14 at 21:10
source share

This solved my problem:

Enable the Google+ API. This is the question and is the main cause of the problem in this question. If you do not, it is easy to miss that the request for /account/ExternalLoginCallback includes &error=access_denied , and this is because Google did not respond to permissions, request OWIN for the main Google+ profile. I can’t say whose fault it is, Google or Microsoft.

To enable the Google+ API in the Developer Console, click the API on the left, find Google+ and click "Enable."

+3
Dec 11 '15 at 23:02
source share

I got it to work, just updating the whole nugget package in the application, and it worked.

+3
May 31 '17 at 14:04
source share

I did the following to make it work.

Log in to the developer portal, find your application, and follow these steps.

Application Details> Paid Platforms List Oriented Applications> Select Yes for the website

+1
Sep 12 '14 at 16:23
source share

Today I ran into this problem and it turned out that I defined the deleted cookie after I assigned the providers.

Make sure you post ...

 app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 

before...

 app.UseFacebookAuthentication( appId: "", appSecret: ""); 
+1
Oct 26 '16 at 20:16
source share

For those experiencing this problem for Web Api. Other solutions do not help AuthenticationManager.GetExternalLoginInfoAsync(); always returns zero, even if the Google Plus API is enabled.

use this user function to get login. Microsoft obviously has an error for GetExternalLoginInfoAsync when requesting through the web API.

 private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer() { ExternalLoginInfo loginInfo = null; var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer); if (result != null && result.Identity != null) { var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier); if (idClaim != null) { loginInfo = new ExternalLoginInfo() { DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""), Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value) }; } } return loginInfo; } 
+1
May 23 '18 at 22:24
source share

Although the answers above are fine, none of them worked in my case - I checked and double-checked Google’s settings and agreed with Chris Moskini that there was a lot of misleading information.

For me, this was the moment when I realized that my "Out of Service" service was not running ! No errors (since the login was the first thing I tried after a reboot when the public service was set up to start manually on the machine), just Null from GetExternalLoginInfoAsync

Hope this helps someone else.

0
Feb 15 '16 at 13:47
source share

After a long search and scratches on my head, and also after numerous answers from the red herring here in Stackoverflow, I finally looked at all my options on my Google dev console and found a slightly blue [Enable] button on the Google+ API overview page. I clicked on this button and it was good. Forget about all the balloons you read about the callback url and route settings, OWIN anyway redefines the google default / signin-google redirect uri url and sends you back to ExternalLoginCallback. Just stick to the default implementation, everything will be fine as long as you enable your Google + API.

0
May 12, '16 at 15:17
source share

I also wanted to contribute to this. I recently got this job. I had a problem returning GetExternalLoginInfoAsync, but only during production.

After a lot of searching, I finally found my answer, it was just a problem with my database. In production, I set the wrong connection string so that it does not connect properly, but basically was silent about it. The only thing that happened is GetExternallLoginInfoAsync, which returns null. So check your database connection string if that happens!

In addition, on the side, the only thing needed to get this job was:

  • Set up a project in the Google console
  • Enable Google+ API
  • Copy the client ID and client secret into the Startup.Auth.cs file.

You do not need to enable HTTPS, you do not need to create your own routes. But make sure your database is working correctly!

0
Jan 19 '17 at 11:31 on
source share

It is true that you will need Google Plus enabled. The big thing for me was the project URL. Open the properties window (View → Properties window) in VS, and then right-click the project and select properties. In the small properties window, copy your SSL URL, and then in the larger properties window, select the Web tab and paste this URL into the project URL.

Fixed problem for me.

See more details: https://docs.microsoft.com/en-us/aspnet/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and -openid input

0
Apr 21 '19 at 3:37
source share

For me, I was an old but working .NET 4.6.1 MVC website prior to kernel 1.1. Work stopped before I could get it to work, when I lifted it back, I then switched to 2.x.

My problem was that the callback from Google was received from 404 from my site. I thought this should have hit AccountController.ExternalLoginCallback so I added [Route(...)] to it and, of course, the Google callback got into action.

It then hits the null returned in this line (which maniac returns null ?)

 var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync(); 

I reverse engineer this to find under the hood it will eventually get a handler for ExternalScheme which for me was a cookie handler!

Everything seemed wrong, and somehow I felt that the middleware was just to catch the callback URI, so I deleted my [Route(...)] and the 404 problem returned.

Then I discovered that I needed to add this during startup.

 applicationBuilder.UseAuthentication(); 

This solves 404 but gives another problem.

No authenticationScheme scheme was specified, and DefaultSignInScheme was not found.

By adding a default schema here, I am fixing the error above.

 serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme) .AddGoogle(googleOptions => Configuration.Bind("OAuth2:Providers:Google", googleOptions)) .AddExternalCookie(); 

Now AccountController.ExternalLoginCallback again called by some kind of magic, but I returned to the null return value.

I added this code above the offensive line, which, in fact, happens under the hood (looking at the Microsoft code on GitHub). Interestingly, h is of type CookieAuthenticationHandler and has all my requirements and information from Google inside! a

 var authHandler = this.HttpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>(); var h = await authHandler.GetHandlerAsync(this.HttpContext, IdentityConstants.ExternalScheme); var a = await h.AuthenticateAsync(); var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync(); 

By digging into GitHub and copying the pasted internal code that it runs into my controller, I see that it was unable to find ClaimTypes.NameIdentifier in my statements, this is the ProviderKey used later.

Hmm ...

Worried that I used the old 1.x AccountController code with the new 2.x identification bits, I found some examples that still use this stuff, and some examples that also use Razor Pages for all of this. I will continue with what I have.

Next, I’m going to explore the mapping of additional elements of a Google user JSON payload to claims. I think that if my Google Account ID (I think numeric) were matched, then everything would work.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=aspnetcore-2.2

Final fix

I finally resolved the issue by adding a “sue action” to pull my Google id from the JSON returned from Google!

 serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme) .AddGoogle(googleOptions => { Configuration.Bind("OAuth2:Providers:Google", googleOptions); googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string"); }) .AddExternalCookie(); 

The sub field contains what ends up in the nameidentifier claim, and then in the ProviderKey , what the AccountController wants.

0
Jun 11 '19 at 20:45
source share

All other answers did not allow this for me, so if you are in the same boat, make sure that the action of your registration controller has the RequireHttps attribute:

  // GET: /Account/LoginRegister [AllowAnonymous] [RequireHttps] public ActionResult LoginRegister() { return View(new RegisterLoginViewModel()); } 
-one
Oct 10 '15 at 0:41
source share



All Articles