Invalid Authentication Token Error with Microsoft Graph for token obtained through Azure's built in app services authentication - azure-mobile-services

On the backend of my Azure Mobile App, I am using Azure's built in authentication services to obtain an access token when a user logs on to my app via a Microsoft account. I am successfully obtaining that token.
However, I then attempt to call out to the Microsoft Graph to obtain the authenticated user's name, email, and ID. Azure's log stream shows me this error:
MicrosoftGraphServiceException:
Code: InvalidAuthenticationToken
Message: CompactToken parsing failed with error code: 8004920A
Here is the applicable code:
[MobileAppController]
public class MicrosoftAccountController : ApiController
{
MicrosoftAccountCredentials credentials;
// GET api/<controller>
public async Task<DataObjects.User> Get()
{
if (credentials == null)
{
credentials =
await this.User.GetAppServiceIdentityAsync<MicrosoftAccountCredentials>(this.Request);
var accessToken = credentials.AccessToken;
}
GraphServiceClient graphClient =
new Microsoft.Graph.GraphServiceClient(new DelegateAuthenticationProvider((requestMessage) =>
{
requestMessage.Headers.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
return Task.FromResult(0);
}));
Microsoft.Graph.User graphuser = await graphClient.Me.Request().GetAsync();
}
Thanks for you help!

According to your description, I assumed that you could directly access your mobile app https://{your-app-name}.azurewebsites.net/.auth/login/microsoftaccount via the browser and login with your MSA. After logged, you could try to access https://{your-app-name}.azurewebsites.net/.auth/me to retrieve the logged user info as follows:
Then, you could retrieve the access_token and try to simulate the request via postman to narrow this issue:
However, I then attempt to call out to the Microsoft Graph to obtain the authenticated user's name, email, and ID.
I assumed that you could call await App.MobileService.InvokeApiAsync("/.auth/me", HttpMethod.Get, null); in your mobile client after user logged to retrieve the user info. I found that you created a custom WebAPI and extracted the token based on the current request and used the graph client to retrieve the user info, I did not check your code, but you could remote debugging your mobile app to troubleshoot with your code.
Moreover, you could follow App Service Token Store for more details about App Service Authentication / Authorization.
UPDATE:
However, I then attempt to call out to the Microsoft Graph to obtain the authenticated user's name, email, and ID. Azure's log stream shows me this error
I checked your code and found that Microsoft Graph targets at graph.microsoft.com, while the MSA login for App Service Authentication/Authorization used the Live SDK. And the Live SDK is deprecated, I did not found any client SDK for consuming the Rest APIs, I assumed that you could just create the WebRequest and access the Live SDK REST API by yourself.

Related

Do you need to use the OAuth flow to access your own dropbox account?

I'm writing a dropbox integration against my own account. When file get dropped I respond to a webhook notification and import the files into one of our backend systems.
It's all done in back end server code and there is no real opportunity to pop up a UI to get me to sign in.
I've developed it so far using the access token you can get from the app console but that expires after a few hours.
Are there any auth shortcuts when using the API with just your own account?
I've figured out some shortcuts for myself
First off all as its a background process it needs to be running with "offline" access and using refresh tokens to acquire short lived access tokens.
As there is no UI and its only for my own account I can get an authorisation code via the browser from this URL
https://www.dropbox.com/oauth2/authorize?client_id={{Your APP ID Here}}&token_access_type=offline&response_type=code
then use POSTMAN to get an access Token & Refresh Token:
In Postman:
Post to https://api.dropboxapi.com/oauth2/token
Authorisation Basic
UserName = {{AppKey}}
Password = {{AppSecret}}
Body :x-ww-form-urlencoded
code = <<Auth Code From Browser>>
grant_type = authorization_code
This produces a result with an access_token and a refresh_token
The refresh token will only expire if I withdraw access so that will be safe to add into my config and use to request access tokens or connect to the client.
In my case its c#
using (var dbx = new DropboxClient(refreshToken,appKey,appSecret))
{
var myAccount = await dbx.Users.GetCurrentAccountAsync();
String.Format("{0} - {1}",
myAccount.Name.DisplayName,
myAccount.Email)
.Dump("Account Details");
}

Github OAuth Provider - Get username or id

I'm using the Firebase Authentication services to authenticate users using Github as the provider. The OAuth response returns the access-token for the user along with some other information (e.g. email, name...). For persistence-purposes I need to save the authenticated users username or id, but I can't seem to find that information in the OAuth callback.
Am I missing something or is the user data just not provided using OAuth?
It is not clear which SDK you are using but Firebase auth returns additionalUserInfo form OAuth providers. For example, with the JS SDK, you can get the additionalUserInfo as follows:
firebase.auth().signInWithPopup(new firebase.auth.GithubAuthProvider())
.then(function(result) {
console.log(result.additionalUserInfo.username);
console.log(reuslt.additionalUserInfo.profile);
})
.catch(function(error) {
// Some error occurred.
});

How to obtain access token in Cloud Functions for Firebase when user signs up?

When a client signs in with Github, I would like to trigger a Cloud Function that retrieves the user's profile data from Github and stores it in /users/{uid}/profile in the Realtime database.
I can trigger my cloud function when a new user signs up using:
exports.fetchProfile = functions.auth.user().onCreate(event => {
// user = event.data
// uid = user.uid
// access_token = ???
// todo: request user profile from Github using access_token
// todo: save profile in /users/{uid}/profile
});
But, how do I obtain the user's access_token needed for making the Github profile request? Thanks.
What I have tried:
On the client, use FirebaseAuth to get the Github access_token.
Create a Firebase credential using the access_token from (1).
Sign in with the credential from (2), I get a FIRUser in success callback, from which I can obtain uid.
I write {uid: access_token} to a queue in the Realtime database, this in turn triggers my cloud function that does the profile retrieval.
All these just to get the user's access_token, can I do better?
You can't do it with the user creation trigger.
You have multiple options:
after sign up, get the access token from the client and saved it in the real-time database under a location accessible by the specified user. You can then set a cloud functions database trigger for that location. When that is triggered, you get the access token and make your API call to GitHub and get the data and do whatever you want with it.
Run everything on the client side. Since you have the access token after sign up in the client (browser), make the API call to GitHub and then save the profile data in a database location accessible by the user only. You can add a cloud function to trigger on changes to that location if you need to run additional admin operations.
By the way, Firebase Auth (4.0.0) now returns additional user data. Check: https://firebase.google.com/docs/reference/js/firebase.auth#.UserCredential
You can get the additional data by calling result.additionalUserInfo.profile, or the GitHub username: result.additionalUserInfo.username.

Is it possible to use google as authentication server only without using any API and how

I have a C# desktop application that works against a server(play framework 2.5 if it matters)with REST API calls.
I want to authenticate the calls from the client(desktop app) to the server using gmail accounts.
now before displaying the flow, some clarifications:
the client app is sometimes unattended(I receive the username+password from somewhere else) - meaning displaying a user consent screen is not an option
I have no interest in any Google APIs! I only want to access my server REST API.
I only need Google for the authentication stage
the wanted flow:
In the client:
get the username and password from the user(as mentioned can be done non interactively)
authenticate the user against google and get a token
send a request to the server including the token
In the server:
"decode" the token back into username
check if this user is authenticated to do the call and act accordingly
if possible - how would you do it?
You'll first need to setup a new project on the Google API Manager (that's where that content Guid is coming from below in the meta tag).
On the client side, here's how you can use Google's Sign-In button template to initialize the login & grant of permissions process:
<meta name="google-signin-client_id" content="29chqvu3ghgtte1.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js?onload=onLoad" async defer></script>
<div id="google-signin-button"
class="g-signin2"
data-width="170"
data-height="30"
data-onsuccess="onSignIn"
data-onfailure="onSignInFailure">
</div>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
var idToken = googleUser.getAuthResponse().id_token;
}
Then you can simply send this idToken to the server/api, from where you can do a GET on Google's endpoint to verify this token https://www.googleapis.com/oauth2/v3/tokeninfo?id_token={0}. There are of course numerous other ways in which you can validate the token (and actually get a handle on it, of course).
This would be the gist of it (excluding the non-interactive user login - keep in mind you'll also need the user to grant permissions).

how to use access token to create a new user account using google provisioning api in .net

I am trying to create a dektop application to create new user account into particular user group using Provisioning API of google.
I am using some >Net libraries in my code , here is how my code looks like.
string token = GetNewAuthenticationToken("domain.name", "adminEmail", "adminPassword");
AppsService service = new AppsService("domain.name", token);
service.CreateUser("usernametest", "userfirstname", "userlastname","userpasswordtest12345");
But I am getting this error,
Execution of request failed: https://apps-apis.google.com/a/feeds/domain.name/user/2.0
I know it has something to do with token I am getting, can anybody have any idea on how to pass the token with service.createuser method?
And also what is use of that client id and client secret code which is generated while registering app on google.