Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net MVC 5 Google Authentication with Scope

I'm trying to get ASP.Net MVC 5 Google OAuth2 authentication working correctly.

When I set pass in a GoogleOauth2AuthenticationOptions without any scope, then I'm able to log in successfully.

var googlePlusOptions = new GoogleOAuth2AuthenticationOptions
{
    ClientId = googleClientId,
    ClientSecret = googleClientSecret,
    SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
    Provider = new GoogleOAuth2AuthenticationProvider()
    {
        OnAuthenticated = async ctx =>
        {
            ctx.Identity.AddClaim(new Claim("urn:tokens:googleplus:accesstoken", ctx.AccessToken));
        }
    },
};

app.UseGoogleAuthentication(googlePlusOptions);

Then this call will return an ExternalLoginInfo object with all the properties set

ExternalLoginInfo loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();

When I add any scope though, then I don't get any login info returned. It's just null.

var googlePlusOptions = new GoogleOAuth2AuthenticationOptions
{
    ClientId = googleClientId,
    ClientSecret = googleClientSecret,
    SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
    Provider = new GoogleOAuth2AuthenticationProvider()
    {
        OnAuthenticated = async ctx =>
        {
            ctx.Identity.AddClaim(new Claim("urn:tokens:googleplus:accesstoken", ctx.AccessToken));
        }
    },
};

googlePlusOptions.Scope.Add(YouTubeService.Scope.Youtube);

app.UseGoogleAuthentication(googlePlusOptions);

Then the call to get external info just returns null.

ExternalLoginInfo loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();

In the Google dev console, I have the following APIs turned on..

  • Analytics API
  • BigQuery API
  • Google Cloud SQL
  • Google Cloud Storage
  • Google Cloud Storage JSON API
  • Google+ API
  • Google+ Domains API
  • Identity Toolkit API
  • YouTube Analytics API
  • YouTube Data API v3

Something about adding scope to the options is breaking GetExternalLoginInfoAsync.

like image 785
Rob Gibbens Avatar asked Mar 27 '14 14:03

Rob Gibbens


2 Answers

If anyone's still having trouble with this with the latest Microsoft OWIN middleware (3.0.0+)...


I noticed from Fiddler that by default, the following scope is sent to accounts.google.com:

scope=openid%20profile%20email

If you add your own scope(s) via GoogleOAuth2AuthenticationOptions.Scope.Add(...), then the scope becomes:

scope=YOUR_SCOPES_ONLY

Therefore, you need to add the default scopes too (or at least, this fixed the issue for me):

var googlePlusOptions = new GoogleOAuth2AuthenticationOptions {
    ...
};

// default scopes
googlePlusOptions.Scope.Add("openid");
googlePlusOptions.Scope.Add("profile");
googlePlusOptions.Scope.Add("email");

// additional scope(s)
googlePlusOptions.Scope.Add("https://www.googleapis.com/auth/youtube.readonly");
like image 133
Dunc Avatar answered Nov 28 '22 02:11

Dunc


So, I figured this out, with a lot of help from http://www.beabigrockstar.com/blog/google-oauth-sign-asp-net-identity. It turns out that the built in Google authentication provider for MVC is openId only. That's why adding a scope broke it. Using Fiddler, I was able to see the GET request to accounts.google.com, which included "scope=openid" in the querystring.

By switching to the GooglePlusOAuth2 provider in the link above, or on Nuget https://www.nuget.org/packages/Owin.Security.GooglePlus and using the provider name of "GooglePlus", I was able to succesfully add the scopes and still get back the login info from GetExternalLoginInfoAsync.

like image 40
Rob Gibbens Avatar answered Nov 28 '22 02:11

Rob Gibbens