Google Authentication using OWIN Oauth in MVC5 not hitting ExternalLoginCallback function

36,459

Solution 1

Try only this

var googleOAuth2AuthenticationOptions = new GoogleOAuth2AuthenticationOptions
        {
            ClientId = "MYCLIENTID",
            ClientSecret = "MYSECRET",
        };
app.UseGoogleAuthentication(googleOAuth2AuthenticationOptions);

This worked for me

Solution 2

I'm using the default ASP.NET MVC 5 template with Identity Authentication for simplicity, but hopefully this can be modified for different use cases.

StartupAuth.cs

Do not customize the redirect path. It gets replaced by /signin-google anyways and my attempts at getting around that caused "silent" (not in the debugger) Internal Server 500 errors.

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
    ClientId = "whatevs.apps.googleusercontent.com",
    ClientSecret = "whatevs_secrut",
    Provider = new GoogleOAuth2AuthenticationProvider()
});

Make sure to add http://whatever.com/signin-google to https://console.developers.google.com/ in your APIs & auth > Credentials > Redirect URIs section.

RouteConfig.cs

Add a route to a permanent redirect controller action to your routes. Permanent redirects are the only thing that will suffice here. It is not enough to simply direct directly to the Callback URL.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Google API Sign-in",
        url: "signin-google",
        defaults: new { controller = "Account", action = "ExternalLoginCallbackRedirect" }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

AccountController.cs

Permanent redirect to the built-in callback method and you should be fine.

[AllowAnonymous]
public ActionResult ExternalLoginCallbackRedirect(string returnUrl)
{
    return RedirectPermanent("/Account/ExternalLoginCallback");
}

A template project has been posted on GitHub for reference: https://github.com/Pritchard/Test-AspNetGoogleOAuth2Authentication

Solution 3

Make sure you have also enabled the Google+ API in your developer console. It is an additional step after you have your client and secret

Solution 4

As @Ronen said in the comments, this link should solve the issues with Google OAuth in MVC5:

http://blogs.msdn.com/b/webdev/archive/2014/07/02/changes-to-google-oauth-2-0-and-updates-in-google-middleware-for-3-0-0-rc-release.aspx

Also update the OWIN packages from NuGet. This is how my code looks and is working great:

       var googleOptions = new GoogleOAuth2AuthenticationOptions ()
       {
           ClientId = "xxxxxxxxxx",
           ClientSecret = "xxxxxxxxxx",
           CallbackPath = new PathString("/signin-google")
       };
       googleOptions.Scope.Add("email");

       app.UseGoogleAuthentication(googleOptions);
Share:
36,459

Related videos on Youtube

Brad Baskin
Author by

Brad Baskin

Startup Cofounder - BargainsCombined.com - Launching soon

Updated on May 13, 2020

Comments

  • Brad Baskin
    Brad Baskin almost 4 years

    I am currently upgrading my login process for Google to use OAuth before they depricate their OpenID login method.

    The steps I have Identified so far is that I have upgraded the package Microsoft.Owin.Security.Google to version 2.1.0 as this version includes the ability to include options in the UseGoogleAuthentication method.

    I have tried to use Alex Wheat's Solution in the link: Get ExtraData from MVC5 framework OAuth/OWin identity provider with external auth provider

    The code in Startup.Auth.cs (which also includes Facebook authentication) goes from this:

        var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
            {
                AppId = "MYAPPID",
                AppSecret = "MYSECRET"
            };
            facebookAuthenticationOptions.Scope.Add("email");
            app.UseFacebookAuthentication(facebookAuthenticationOptions);
    
            app.UseGoogleAuthentication();
    

    To this:

    var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
            {
                AppId = "MYAPPID",
                AppSecret = "MYSECRET"
            };
            facebookAuthenticationOptions.Scope.Add("email");
            app.UseFacebookAuthentication(facebookAuthenticationOptions);
    
    
            var googleOAuth2AuthenticationOptions = new GoogleOAuth2AuthenticationOptions
            {
                ClientId = "MYCLIENTID",
                ClientSecret = "MYSECRET",
                CallbackPath = new PathString("/en/Account/ExternalLoginCallback"),
                Provider = new GoogleOAuth2AuthenticationProvider()
                {
    
                }
            };
    
            app.UseGoogleAuthentication(googleOAuth2AuthenticationOptions);
    

    After I add options to the Google Authentication, my app does not allow the ExternalLoginCallback action to be called for either google or facebook (no changes to facebook code but the issue still affects it).

    On the front end, after clicking the external login buttons, the page redirects me to the link below and returns an empty white screen

    https....../en/Account/ExternalLoginCallback#__=_ (There is actually only a single underscore before the = sign, SO syntax removes it if I have it as it appears on my address bar).

    for facebook and

    https....../en/Account/ExternalLoginCallback

    for google. It does not hit the controller method below as it normally does (I have tried to place debug breakpoints within this function and it never gets stopped when there are google authentication options.

        // GET: /Account/ExternalLoginCallback
        [AllowAnonymous]
        public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
        {
    

    If I remove the authentication options from Google Authentication, it just reverts back to the old OpenID login and works fine again.

    Am I missing something simple here? or is there something bad happening inside the Owin.Security.Google Library that is causing the problem?

  • Brad Baskin
    Brad Baskin about 10 years
    This fixes the issue that was happening with my facebook authentication. When I use google it tries to go to the following link on my site as the callback https.../signin-google Do you know how to set the callback path? when I use the callbackPath that I had in my original post, the same problem occurs as my original question. The clientID is set in google to point to my ExternalLoginCallback function but it does not actually call it on return.
  • Brad Baskin
    Brad Baskin about 10 years
    Just to follow up, using this method seems to automatically use the signin-google request in the address. What I did to fix this was to change my google callback location in the google console to point to this address. I also added a route in my RouteConfig file ` routes.MapRoute( name: "signin-google", url: "signin-google", defaults: new { controller = "Account", action = "ExternalLoginCallback" } );` Thanks for your help @suhas-joshi
  • Suhas Joshi
    Suhas Joshi about 10 years
    @Brad: Sorry couldn't reply soon enough but glad you found the solution
  • Ronen Festinger
    Ronen Festinger over 9 years
    Look what I found: details about those changes blogs.msdn.com/b/webdev/archive/2014/07/02/…
  • Michal Hosala
    Michal Hosala over 8 years
    Could you perhaps shed some light on why do we need ExternalLoginCallbackRedirect at all? why not to simply use ExternalLoginCallback directly in the route config?
  • Admin
    Admin over 8 years
    @MichalHosala My guess is it's possible to do that. This question is from February of this year, however, and at this time I'm no longer involved in the work necessary to recollect the context. If there's a simpler way to accomplish the task, I say go for it!
  • Michal Hosala
    Michal Hosala over 8 years
    Thanks for the response, however, if I use the ExternalLoginCallback then, surprisingly, it stops working and I am not redirected into ExternalLoginCallback after login at all... So your code seems to be correct, just no idea why do we need this extra step :)
  • Michal Hosala
    Michal Hosala over 8 years
    For the future reference - based on offical guidelines for integrating Google authentication with MVC app I do not see any reason why to modify RouteConfig.cs and AccountController.cs at all. The google auth. keeps on working (for me) even after removing the changes in those two files.
  • Admin
    Admin over 8 years
    @MichalHosala I think that link might merit an answer of its own :) My response to this question was specifically geared toward the issues I encountered with the example site that came packaged with the Visual Studio template.
  • Mark Bell
    Mark Bell over 8 years
    This fixed it for me, ta! Sadly, this is not mentioned at all in any of the Microsoft walkthroughs...
  • rsrobbins
    rsrobbins almost 8 years
    Adding the code to RouteConfig.cs solved my problem. Thanks!
  • William Daugherty
    William Daugherty over 5 years
    This did it for me! HOURS of troubleshooting, thanks!
  • TK71
    TK71 over 5 years
    FYI, in case you missed it while you were setting up the Google part, you must also enable the Google+ API. If you do not, the above code will cause a "loop" where your app will know you are logged in, but can't get external login info, so when you try to log in using Google it just keeps returning to the Login page (and won't throw an error).