MVC Oauth2 Accessing Google Analytics - asp.net-mvc

I've setup my asp.net MVC website to allow login through Google:
In App_Start\Startup.Auth.cs
var googlePlusOptions = new Microsoft.Owin.Security.Google.GoogleOAuth2AuthenticationOptions
{
ClientId = "someid",
ClientSecret = "somesecret",
SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
};
googlePlusOptions.Scope.Add("email");
googlePlusOptions.Scope.Add("https://www.googleapis.com/auth/analytics.readonly");
app.UseGoogleAuthentication(googlePlusOptions);
I thought I would see an Authorization code in the claims list, but there is nothing there. Where do I get the Authorization code? Any tutorials or help would be greatly appreciated, I'm new with MVC, OAuth, and Google APIs and feel a bit over my head.

Related

Function to request user claims and token from Identity Server?

What is the best way to retrieve user claims and tokens after logging into identity server?
I have a .Net Core MVC web app. I redirect to an identity server, log in, then redirect back to my web app.
From my app I would then like to request user claims and token from identity server.
Is there a method call to do this?
I have gone through the tutorials and searched around and found libraries (oidc-client-js, oidc.usermanager for javascript that handles this. OidcClient for native c# apps) that handle this behavior, but not for c# web app - so I realize maybe what I'm asking for is not the convention but I'd still appreciate any insight on this.
Edit:
To elaborate, in the c# web app tutorials, specifically tutorial #3, I fail to see how claims and token information become retrievable from from figure 1 to figure 2.
Furthermore, I'm trying to call and handle these objects in c#, not html.
Figure 1
Figure 2
Thank you
In controller , you can retire claims like
var claims = User.Claims;
Get the access token/id token/refresh token :
var accessToken = HttpContext.GetTokenAsync("access_token").Result;
var idToken = HttpContext.GetTokenAsync("id_token").Result;
var refreshToken = HttpContext.GetTokenAsync("refresh_token").Result;
To achieve that , you need register your OIDC middleware inside ConfigureServices as follows (making sure to set SaveTokens to true) :
.AddOpenIdConnect(options => {
// Set all your OIDC options...
// and then set SaveTokens to save tokens to the AuthenticationProperties
options.SaveTokens = true;
});
In mvc razor page , you can get the information :
#using Microsoft.AspNetCore.Authentication
#{
ViewData["Title"] = "Home Page";
}
<dl>
#foreach (var claim in User.Claims)
{
<dt>#claim.Type</dt>
<dd>#claim.Value</dd>
}
</dl>
<dt>access token</dt>
<dd>#await ViewContext.HttpContext.GetTokenAsync("access_token")</dd>
<dt>ID token</dt>
<dd>#await ViewContext.HttpContext.GetTokenAsync("id_token")</dd>
<dt>refresh token</dt>
<dd>#await ViewContext.HttpContext.GetTokenAsync("refresh_token")</dd>

where do i modify 'signin-google' in owin security for google redirect url?

Im working on asp mvc 5 with google oauth login,
I followed a tutorial installing owin security and set the google redirect url to be localhost/myapp/signin-google,
my question is where can i change the localhost/myapp/signin-google to be something else like localhost/myapp/mycallback ?
i tried change is to be localhost/myapp/signup/ExternalLoginCallback which the actual action, but it didnt work, is 'signin-google' hardcoded in owin security??
Adem is right. Here is how you change it:
var options = new GoogleOAuth2AuthenticationOptions
{
ClientId = "Your Client ID",
ClientSecret = "Your Client Secret",
CallbackPath = new PathString("/myapp/mycallback")
};
app.UseGoogleAuthentication(options);
Please see this link for more details.

MVC 5 Gmail API Integration

I'm trying to use the GMail API in an MVC 5 project, but I seem to having difficulties on how to achieve that using the Owin Middleware for Authentication
I'm able to login via a Google account, and I can also get the user token as such
var googleOptions = new GoogleOAuth2AuthenticationOptions
{
ClientId = "xxx",
ClientSecret = "yyy",
SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
Provider = new GoogleOAuth2AuthenticationProvider()
{
OnAuthenticated = async ctx =>
{
ctx.Identity.AddClaim(new Claim("urn:tokens:google:accesstoken", ctx.AccessToken));
}
},
};
app.UseGoogleAuthentication(googleOptions);
I get the access token as I would expect, but Google Quicktart Tutorial found here seems to suggest a very different way to accomplish the Authentication
Is there a way I can use this AccessToken to create the objects required in the tutorial ?
Or are these two completely different?

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.
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");
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.
The changes Google has made to their auth mechanisms have been reflected in version 3.0.0 of Microsoft Owin middleware. As you have identified correctly, one of the changes have been moving the OAuth endpoint to Google+ (https://www.googleapis.com/plus/v1/people/me).
So, the key is to:
upgrade the OWIN middleware to version 3.0.0
enable Google+ API for your app in Google Developers Console

How do I work with Google Analytics oAuth in a WebAPI?

I am building an extension for open source ASP.NET CMS Umbraco where I want to fetch the analytic's from the user's account once they have authorised via oAuth.
The example MVC 4 snippet over on the Google API .NET wikiw page for oAuth seems to only work with a controller and not a WebAPI controller as far as I can tell, is this right?
AuthorizationCodeMvcApp(this, new AppFlowMetaData()).AuthorizeAsync(cancellationToken);
The first parameter in the example expects it to be a regular MVC Controller
https://code.google.com/p/google-api-dotnet-client/source/browse/Src/GoogleApis.Auth.Mvc4/OAuth2/Mvc/AuthorizationCodeMvcApp.cs
So my question is really, how do I work with oAuth with a WebAPI in mind, as I want to return stats back from the API as JSON from the WebAPI so I can use a client side library such as AngularJS to bind the JSON returned to the HTML view?
I would love for any ideas, feedback or suggestions on how I could solve this please.
Thanks,
Warren :)
I have looked into your problem and the i have tested the service account solution. It's tricky to setup but when it runs it works.
This is the code I used in a webapi controller :
String serviceAccountEmail = "805395301940-cu3nhkuqi4ipa3453o276bar5u2e70lq#developer.gserviceaccount.com";
var cert = HttpContext.Current.Server.MapPath("/key.p12");
var certificate = new X509Certificate2(cert, "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { AnalyticsService.Scope.Analytics }
}.FromCertificate(certificate));
var service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential
});
//var ga = service.Data.Ga.Get("ga:31335471", "2013-01-01", "2013-01-31", "ga:visits");
// Not Working Currently in Beta
//var ga = service.Data.Realtime.Get("ga:31335471", "ga:activeVisitors");
var ga = service.Management.Profiles.List("~all", "~all");
return ga.Execute();

Resources