25

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?

Community
  • 1
  • 1
Brad Baskin
  • 1,265
  • 2
  • 14
  • 20

4 Answers4

21

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

  • 2
    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? – Michal Hosala Sep 23 '15 at 23:39
  • @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! –  Sep 24 '15 at 04:28
  • 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 Sep 24 '15 at 10:53
  • For the future reference - based on [offical guidelines for integrating Google authentication with MVC app](http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on#goog) 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. – Michal Hosala Sep 25 '15 at 00:58
  • @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. –  Sep 25 '15 at 04:58
  • Adding the code to RouteConfig.cs solved my problem. Thanks! – rsrobbins Jul 19 '16 at 20:34
  • 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). – TK71 Jan 22 '19 at 19:30
15

Try only this

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

This worked for me

Suhas Joshi
  • 1,042
  • 9
  • 11
  • 2
    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 Apr 15 '14 at 23:04
  • 14
    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 – Brad Baskin Apr 15 '14 at 23:18
  • @Brad: Sorry couldn't reply soon enough but glad you found the solution – Suhas Joshi Apr 16 '14 at 17:30
  • Look what I found: details about those changes 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 – Ronen Festinger Dec 20 '14 at 21:45
13

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

Aaron Sherman
  • 3,789
  • 1
  • 30
  • 33
3

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);
Rick
  • 31
  • 1