Google OAuth 2.0 and Datastore Need - oauth

I am migrating code from GDATA API to Google ADMIN Directory API (User Provisioning). Migrated code is working fine with the new ADMIN API.
I created a service account in Developers Console, then provided it domain-wide access, using the code below to create the GoogleCredential object.
I am using two-legged OAuth. GoogleCredential takes care of automatically "refreshing" the token so for each API call I am getting new an Access token.
Do I need to use Datastore to persist access token? Whats the advantages of using Datastore and is there any issues in not using Datastore while using OAuth 2.0 ?
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(serviceAccountID)
.setServiceAccountScopes(scopes)
.setServiceAccountPrivateKeyFromP12File(new File(serciceAccountPKCSFilePath))
.setServiceAccountUser(serviceAccountUser)
.build();
// Create the Directory
Directory directory = new Directory.Builder(httpTransport, jsonFactory, credential)
.setApplicationName(applicationName)
.build();
// Makes the actual call to google to create user
user = directory.users().insert(user).execute();

Related

Should the AngularJS application send the AuthToken or IDToken? When do use ID token vs Auth Token?

I have the following configuration in my ASP.NET Core Web API:
// Adds Microsoft Identity platform (AAD v2.0) support to protect this Api
services.AddMicrosoftIdentityWebApiAuthentication(configuration);
services.AddControllers(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.RequireClaim("email")
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
});
I have an Angular client application that sends the AuthToken with each request.
Below is my asp.net WEB API controller
[Route("[controller]")]
public class UserController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
//Get User Email ID from Claims
//Get User details from Database
//Return the User Details
...
}
}
In the asp.net WEB API controller, I need to get the Email claim from the Auth Token.
Should the AngularJS application send the AuthToken or IDToken? When do use ID token vs Auth Token?
Update :
OpenID Connect is built on top of OAuth2.
WEBAPI:
An access_token is useful to call certain APIs in Auth0 (e.g. /userinfo) or an API you define in Auth0.
WEBAPP:
An id_token is a JWT and represents the logged in user. It is often used by your app.
CONSOLE/MOBILE APP :
A refresh_token (only to be used by a mobile/desktop app) doesn't expire (but is revokable) and it allows you to obtain freshly minted access_tokens and id_token
My question still remains the same? If the webapp or console app requires the claims, should we need AuthToken?
Update:#2
https://www.youtube.com/watch?v=M4JIvUIE17c
Please note that, access tokens are used to perform actions like authentication and authorization to protect the web APIs.
ID tokens are generated by authorization server and contains the claim of the user information, and these claims can be used for the UX in your application.
AFAIK as your application sends the AuthToken with each request you can use the same token to get Email claim.
Make sure to add email API permissions like below:
Go to Azure Portal -> Azure Active Directory -> App Registrations -> Your App -> Api Permissions
Try to give the scope = api://{app id of the AAD app which represents the web api}/.default openid as mentioned by Allen Wu in this SO Thread.
I tried to generate an access token with above scope and got the claims successfully like below:
Please note that, you can get the email claim either by using AuthToken or IDToken.

How Google OAuth 2.0 Java library take care of Access Token! if Client ID, Secret and Refresh Token is provided.?

Code snippets for Building OAuth 2.0 credentials :
Credential credential = new GoogleCredential.Builder().setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setClientSecrets(myAppClientID, myAppSecret)
.build();
credential.setRefreshToken(userRefreshToken);
I am using Java Library in order to get the Google Analytics Data.
I do have Client ID, Secret and Refresh Token. I am accessing Google Analytics API though this credentials information,
My question is, Will Google OAuth 2.0 take care of Access Token Automatically? Or Do i need to handle it manually with some mechanism? If i am not passing access token to this code.
From the Credential API doc:
Thread-safe OAuth 2.0 helper for accessing protected resources using
an access token, as well as optionally refreshing the access token
when it expires using a refresh token.
So if you don't specify an access token, it will be automatically fetched using the refresh token. But since you already have an access token, I would say it's good to set it - it will save the first network call to the /token endpoint.

Right Access Token for Microsoft Graph API / Office Planner Data

I try to request all Office Planner Plans and Tasks of all users via Microsoft Graph API. This is a Console Application and should run as Azure WebJob. I'm struggling with the Access Token.
With an user Token I receive 403 (Forbidden) on https://graph.microsoft.com/beta/users/{userid}/plans.
AuthenticationContext authenticationContext = new AuthenticationContext($"https://login.microsoftonline.com/{TenantName}", false);
var authTask = authenticationContext.AcquireTokenAsync("https://graph.microsoft.com", _config.ClientIdUser, new UserPasswordCredential(_config.Username, _config.Password));
uthTask.Wait();
AuthenticationResult userAuthnResult = authTask.Result;
var token = userAuthnResult.AccessToken;
With an app only Access Token I can't request the Graph API. I read somewhere that I have to use an app+user token but how can I request such a Token?
You can only request an app+user token in the first place from an interactive application where the user can consent and provide their credentials in a Microsoft-owned user experience. As part of that OAUTH flow you can then request a refresh token which you can store securely and pass to your webjob to run the later task.

Accessing Microsoft Graph API without using login page

I would like to access a user's one drive to upload a document or retrieve a document using Graph API.
I've seen multiple examples over the net which requires using the standard login page for the user to login. You need to get the authorization code from the login page and then use it to get a token, which finally can be used to access a resource like drive.
Am looking for a way to do this without going through the login page. I can have my own login page where I can request user to login.
In short, I want to access drive resource of Graph API using a REST client like Postman (right from authorization to accessing the resource). Is this possible?
Yes, it is possible if you have the right information - all you need to do is to get a delegated access token.
Explanation:
When dealing with access to resources, Microsoft Graph has two levels of access token requirements:
Most methods support Application only tokens, meaning once an OAuth app has consent it can access the resource whenever it wants.
But for some methods, it is not enough (they are too sensitive for an automated process) and require a Delegated token, meaning token which contains both a valid Client and User. You can see in each method documentation which token it requires.
Normally delegated access tokens are the result of the two major OAuth flows which require user interaction (Authorization Code Grant and Implicit Grant) but you can also get them from two other flows: Resource Owner Credentials Grant and On-Behalf-Of Grant, which are both supported by Microsoft.
For a full guide on how to setup everything you need in order to use those flows (including Postman examples) you can look at my article:
Getting Access Token for Microsoft Graph Using OAuth REST API
Yes this is possible. Essentially you grant access application access to Graph API instead of a user.
The documentation for such access is here:
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
You'll still need to a request a bearer token to send with all your REST requests, but the bearer token will be for the application itself and not a user.
I set this up for one of my applications using the Graph SDK for .NET, so if you need specific examples for Graph SDK for .NET let me know.
Although this is possible, it's strongly recommended not to do this for individual user access. The Microsoft Graph only supports OAUTH 2.0 as its authZ protocol, and we recommend that you use the flows within OAUTH where the trusted authority be the one to directly handle login credentials. Allowing application code to provide the forms UI for login credentials would open up the attack vector where your app would have direct access to the user's O365 password, which is not a secure approach.
I've found the documentation is not helpful, especially in terms of trying to acces the Graph API in the application context. But, I managed to get the access token in the context of the application here:
private static async Task<string> AcquireToken()
{
var tenant = "yourtenant.onmicrosoft.com";
var resource = "https://graph.microsoft.com/";
var instance = "https://login.microsoftonline.com/";
var clientID = "YourappID";
var secret = "YourAppSecret";
var authority = $"{instance}{tenant}";
var authContext = new AuthenticationContext(authority);
var credentials = new ClientCredential(clientID, secret);
var authResult = await authContext.AcquireTokenAsync(resource, credentials);
return authResult.AccessToken;
}
Yes, It is possible to access onedrive shared folder with the help of shared url without userlogin.
first you need to get an access token, to hit any microsoft graph API you need access token. follow the link to get access token without user login access token
Encode shared url.
string sharingUrl = "https://onedrive.live.com/redir?resid=1231244193912!12&authKey=1201919!12921!1";
string base64Value = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(sharingUrl));
string encodedUrl = "u!" + base64Value.TrimEnd('=').Replace('/','_').Replace('+','-');
Discovering an endpoint https://learn.microsoft.com/en-us/onedrive/developer/rest-api/concepts/direct-endpoint-differences?view=odsp-graph-online#discovering-an-endpoint
-for OneDrive personal accounts https://api.onedrive.com/v1.0/shares/{shareIdOrUrl}/driveItem?$expand=children
OneDrive for Business and SharePoint
https://graph.microsoft.com/v1.0/shares/{shareIdOrUrl}/driveItem?$expand=children

OWIN OAuth Authorization Server and individual accounts

I have an application that has been under developpment for quite a while now.
We used OWIN with individual accounts.
The application is asp.Net MVC with WebApi and AngularJs frontend.
The API grew quite a lot and we have cases where we need to give access to clients to the API directly.
Problem is that it is secured using CookieAuthentication.
I would like to use the OAuth that is packaged with OWIN and directly available (though a lot of the implementation is up to the developer as it looks like).
Is it possible to add implementation of the Authorization server (http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server) in the same application or should I deploy another server?
The whole thing is that nothing should change for the users of the web site that is currently deployed, this is just an extra feature to help API security.
Thanks
Yes it's possible to implement your Authorization Server to grant client access to your API.
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/OAuth/Token"),
AuthorizeEndpointPath = new PathString("/Api/Account/ExternalLogin"),
Provider = new MyOAuthAuthorizationServerProvider()
};
I leave the implementation of the OAuthAuthorizationServerProvider to you but you can find some inspiration with the Thinktecture Identity project.
Last step is to register your new middleware:
// Enable the application to use bearer tokens to authenticate users (Authorization Server and Resource Server)
app.UseOAuthBearerTokens(OAuthOptions);
You can then send requests to your API with the access token you received from your OAuth provider using the 'client_credentials' grant type.
Hope it helped.

Resources