Mobile Services Authentication with Facebook always gives Unauthorized error - facebook

I've been trying to create unity application and connect it with mobile services. I'm trying to do FB authentication and here's what I've done on my checklist :
Registered my FB App Id and App secret properly on mobile services.
For testing I use FB tools to generate access token for now.
Here's my code to login to FB using Restsharp :
// token is hardcoded with access token from FB tools for test
AuthenticationToken authToken = CreateToken(provider, token);
_LoginAsyncCallback = callback;
var path = "/login/" + provider.ToString().ToLower();
var baseClient = new RestClient(_baseEndPoint);
var request = new RestRequest(path, Method.POST);
var json = SerializeObject(authToken);
request.RequestFormat = DataFormat.Json;
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", json, ParameterType.RequestBody);
var handle = baseClient.ExecuteAsync<MobileServiceUser>(request, LoginAsyncHandler);
provider is facebook and my post is "access_token":"XXXXXXXX" so this should be correct right?
I always get this error :
Rest Response:{"code":401,"error":"Error: The Facebook Graph API access token authorization request failed with HTTP status code 400"}
I've tried many FB app settings and generate new access tokens from FB tools, etc but nothing seems to work. I'm at my wits end on this

Related

MSAL, Azure MobileService and Auto REST calls get 401 Unauthorized

I have an app (currently in UWP) that makes use of MobileServiceClient and AutoRest to an Azure App Service API App. I successfully used the winfbsdk and can authenticate thru that and then get it to login to MobileService.LoginAsync with the FB access token as a JObject. I also take that JObject and send it in the x-zumo-auth header when making calls to the API App via AutoRest within the app.
What I would like to do is be able to authenticate using MicrosoftAccount. If I use MobileService.LoginAsync, I cannot get the proper token and pass it along to AutoRest - it always comes back as 401 Unauthorized.
I tried to used MSAL, but it returns a Bearer token and passing that along also comes back as 401 Unauthorized.
Is there any good way to do this? I started on the route of MSAL since that would support Windows desktop, UWP and Xamarin Forms which will be ideal. I just need info on how to get the proper token from it to pass along to an AutoRest HttpClient that goes back to the Azure App Service API App.
Update:
If I use the following flow, it works with Facebook, but not with MicrosoftAccount.
-Azure AppService with WebAPI (and swagger for testing via a browser)-Security setup through the Azure Dashboard on the service and configured to allow Facebook or MicrosoftAccount
1. On my UWP app, using winfbsdk, I login with Facebook, then grab the FBSession.AccessTokenData.AccessToken and insert that into a JObject:
JObject token = JObject.FromObject
(new{access_token = fbSession.AccessTokenData.AccessToken});
2. Login to MobileServiceClient
user = await App.MobileService.LoginAsync
(MobileServiceAuthenticationProvider.Facebook, token);
Login to API App with HttpClient and retrieve the token to use in X-ZUMO-AUTH
using (var client = new HttpClient())
{
client.BaseAddress = App.MobileService.MobileAppUri;
var jsonToPost = token;
var contentToPost = new StringContent(
JsonConvert.SerializeObject(jsonToPost),
Encoding.UTF8, "application/json");
var asyncResult = await client.PostAsync(
"/.auth/login/" + provider.ToString(),
contentToPost);
if (asyncResult.Content == null)
{
throw new InvalidOperationException("Result from call was null.");
return false;
}
else
{
if (asyncResult.StatusCode == System.Net.HttpStatusCode.OK)
{
var resultContentAsString = asyncResult.Content.AsString();
var converter = new ExpandoObjectConverter();
dynamic responseContentAsObject = JsonConvert.DeserializeObject<ExpandoObject>(
resultContentAsString, converter);
var applicationToken = responseContentAsObject.authenticationToken;
ApiAppClient.UpdateXZUMOAUTHToken(applicationToken);
}
}
}
ApiAppClient.UpdateXZUMOAUTH call just does the following:
if (this.HttpClient.DefaultRequestHeaders.Contains("x-zumo-auth") == true)
{
this.HttpClient.DefaultRequestHeaders.Remove("x-zumo-auth");
}
this.HttpClient.DefaultRequestHeaders.Add("x-zumo-auth", applicationToken);
Any subsequent calls using the ApiAppClient (created with AutoRest from the swagger json of my Azure AppService WebAPI) contain the x-zumo-auth header and are properly authenticated.
The problem occurs when trying to use MicrosoftAccount. I cannot seem to obtain the proper token to use in x-zumo-auth from either MSAL or LoginWithMicrosoftAsync.
For #1 above, when trying for MicrosoftAccount, I used MSAL as follows:
AuthenticationResult result = await MSAuthentication_AcquireToken();
JObject token = JObject.FromObject(new{access_token = result.Token});
And MSAuthentication_AcquireToken is defined below, using interfaces and classes as suggested in the Azure samples: https://github.com/Azure-Samples/active-directory-xamarin-native-v2
private async Task<AuthenticationResult> MSAuthentication_AcquireToken()
{
IMSAcquireToken at = new MSAcquireToken();
try
{
AuthenticationResult res;
res = await at.AcquireTokenAsync(App.MsalPublicClient, App.Scopes);
return res;
}
}
Update - ok with MobileServiceClient, but still not working with MSAL
I got it working with MobileServiceClient as follows:
1. Use MobileService.LoginAsync
2. Take the returned User.MobileServiceAuthenticationToken
3. Set the X-ZUMO-AUTH header to contain the User.MobileServiceAuthenticationToken
user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);
applicationToken = user.MobileServiceAuthenticationToken;
ApiAppClient.UpdateAppAuthenticationToken(applicationToken);
MSAL still not working!
So the original question still remains, what part of the token returned from MSAL do we need to pass on to X-ZUMO-AUTH or some other header so that calls to the Azure AppService WebAPI app will authenticate?
I have an app (currently in UWP) that makes use of MobileServiceClient and AutoRest to an Azure App Service API App. I successfully used the winfbsdk and can authenticate thru that and then get it to login to MobileService.LoginAsync with the FB access token as a JObject. I also take that JObject and send it in the x-zumo-auth header when making calls to the API App via AutoRest within the app.
According to your description, I assumed that you are using Client-managed authentication. You directly contact the identity provider and then provide the token during the login with your mobile back-end, then you could leverage MobileServiceClient.InvokeApiAsync to call your API APP, which would add the X-ZUMO-AUTH header with the value authenticationToken after you invoke MobileServiceClient.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);
What I would like to do is be able to authenticate using MicrosoftAccount. If I use MobileService.LoginAsync, I cannot get the proper token and pass it along to AutoRest - it always comes back as 401 Unauthorized. I tried to used MSAL, but it returns a Bearer token and passing that along also comes back as 401 Unauthorized. Is there any good way to do this?
AFAIK, for the client-flow authentication patterns (AAD, Facebook, Google), the token parameter for LoginAsync would look like {"access_token":"{the_access_token}"}.
For the client-flow authentication (Microsoft Account), you could leverage MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}"), also you could use LoginAsync with the token parameter of the value {"access_token":"{the_access_token}"} or {"authenticationToken":"{Live-SDK-session-authentication-token}"}. I have tested LoginAsync with the access_token from MSA and retrieve the logged info as follows:
In summary, when you retrieve the authentionToken after you have logged with your mobile back-end, you could add the X-ZUMO-AUTH header to each of your API APP requests with the authentionToken.
For more details, you could refer to this official document about authentication works in App Service.
UPDATE
I have checked this https://github.com/Azure-Samples/active-directory-xamarin-native-v2 and used fiddler to capture the network packages when authenticating the user and get an access token. I found that MSAL is working against Microsoft Graph and REST and when the user is logged, you could only retrieve the access_token and id_token, and both of them could not be used for single sign-on with your mobile back-end.
While the official code sample about Client-managed authentication for Azure Mobile Apps with MSA is using the Live SDK. As the Live SDK REST API mentioned about signing users, you could get an access token and an authentication token which is used for single sign-on scenario. Also, I have checked the Server-managed authentication and found that app service authentication / authorization for MSA also uses the Live SDK REST API.
In summary, you could not use MSAL for client-managed authentication with MSA, for client-managed authentication, you need to leverage Live SDK to retrieve the authentication_token then invoke MobileServiceClient.LoginWithMicrosoftAccountAsync("{Live-SDK-session-authentication-token}") to retrieve the authenticationToken from your mobile backend. Or you could just leverage server-managed authentication for MSA. For more details about Live SDK, you could refer to LiveSDK.

How to get Access and Refresh Token while allowing google app by user

I created a google app and in Google app marketplace sdk api filled all the required details and added scopes what i required. And created a webapp in chrome developer dashboard and submitted the app for testing. While first time installing the app from marketplace it get permission from user for the scopes i added in the google app marketplace sdk api. After i click allow it will just install the app. Here how can i retrieve Accesstoken and refresh token or Authorization code while user clicks allow?
I manually get Auth code using this api call:
""https://accounts.google.com/o/oauth2/auth?client_id=CLIENTID &redirect_uri=REDIRECT_URI&scope=email+profile+https://www.googleapis.com/auth/drive&response_type=code&access_type=offline""
In the redirected uri collects access and ref token using this api call:
String accessTokenUrl = "https://accounts.google.com/o/oauth2/token";
String accessTokenUrlParameters = "client_id=" + clientId + "&client_secret=" + clientSecret + "&redirect_uri="
+ redirectUri + "&grant_type=authorization_code&code=" + code;
String accessToken = null;
String refreshToken = null;
try {
HttpClient hc = new HttpClient();
hc.setURL(accessTokenUrl);
hc.setHeader("Content-Length", "" + Integer.toString(accessTokenUrlParameters.getBytes().length));
hc.doPost("application/x-www-form-urlencoded; charset=UTF-8");
}
In this type i get both access and refresh tokens but while installing app for first time how do i get access token using that permissions and scopes. The consent screen while installing app has url like this.
https://accounts.google.com/o/oauth2/auth?client_id=1234567890-1od573nk87eq712l7suam1hu9upa8tm2.apps.googleusercontent.com&origin=https%3A%2F%2Fapis.google.com&authuser=0&login_hint=abcdefghijk#gmail.com&response_type=token&redirect_uri=postmessage&hl=en&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile
but it doesnt have redirect uri and all. How to get access token while allowing this consent screen.

Error in getting active access token from FB

I am having the following code to access FB graph API.
var fb1 = new FacebookClient();
dynamic result = fb1.Get( "oauth/access_token", new
{
client_id = "523408...",
client_secret = "25bd19645....",
grant_type = "client_credentials");
}
var apptoken = result.access_token;
FacebookClient fb = new FacebookClient(apptoken);
dynamic FriendList = fb.Get("me");
string t = FriendList.ToString();
Console.WriteLine(t);
Console.ReadKey();
}
But when I execute it, it is giving this error "(OAuthException - #2500) An active access token must be used to query information about the current user."
Can somebody please tell me how to get active access token using C# code?
The "User" generates the Access Token, not the server.
This page gives you a way to do it thru Facebook CSharp SDK:
I personally use Facebook JavaScript SDK for the Login and pass the Access Token to the server to make calls.
http://facebooksdk.net/docs/web/permissions/
This page gives you information about different authentication workflows:
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0
https://developers.facebook.com/docs/facebook-login/access-tokens/
Hope it helps.
I think access token and user (me) they're not the same person. Check Access token and user. I think we all have this problem.

facebook renew access token

I am building desktop application which should commit some stuffs from file system to Facebook.
Application should not give user login form at all.
C#, VS2010 are used.
I have for Facebook App:
client app id
client secret id
token (which is extended, so it is valid for next 60days).
Idea is to somehow renew the access_token, since Facebook doesn't give permanent access_token (offline_token).
So I have tried this:
var fb = new FacebookClient();
dynamic results = fb.Get("oauth/access_token",
new
{
client_id = "aap_id",
client_secret = "secret_id",
grant_type = "fb_exchange_token",
fb_exchange_token = "existing_token"
});
String newToken = results.access_token;
With this code I get newToken, which is different from existing.
My Question:
If this code is run, lets say day before it is expired, will the new token be valid for new 60 days or not?
Or should again be requested extended token?
Thanks,
Ljiljana.

Could not authenticate with OAuth

I am using Tweetsharp and I am trying to play with the Twitter Application. At present it is a simple console application.
I have searched in the net and found some articles where most of them are stating that after August 16th 2010, the basic authentication for the twitter is no longer applicable. Instead OAuth has come into place.
Henceforth, I have gone to the Twitter Apps and created one for me.(since it's a desktop application, so I choose Application Type to be Client and not browser.)
These are the various information that I got
Consumer key : NxDgjunKLu65CW38Ea1RT
Consumer secret :JOomsRGPTHct9hFjGQOTpxScZwI5K8zkIpOC1ytfo
Request token URL : https://twitter.com/oauth/request_token
Access token URL : https://twitter.com/oauth/access_token
Authorize URL: https://twitter.com/oauth/authorize
As a very basic step what have planned is that, I will write/post some tweet something to my wall.
Henceforth, I made the following(some code has been taken from web as I was using those as a reference)
string consumerKey = "NxDgjunKLu65CW38Ea1RT";
string consumerSecret = "JOomsRGPTHct9hFjGQOTpxScZwI5K8zkIpOC1ytfo";
FluentTwitter.SetClientInfo(new TwitterClientInfo { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret });
//Gets the token
var RequestToken = FluentTwitter.CreateRequest().Authentication.GetRequestToken().Request().AsToken();
var twitter = FluentTwitter.CreateRequest()
.AuthenticateWith(
consumerKey
,consumerSecret,
RequestToken.Token,
RequestToken.TokenSecret)
.Statuses().Update("I am writing my first tweets").AsXml();
var response = twitter.Request();
var status = response.AsStatus();
But the response is
<?xml version="1.0" encoding="UTF-8"?>
<hash>
<error>Could not authenticate with OAuth.</error>
<request>/1/statuses/update.xml</request>
</hash>
I am trying for a long time to understand the problem but all in vain.
I need help.
Thanks
Getting the request token is only the first step of the OAuth process. You need to get the request token, authorize the token, and then trade if for an access token. You then use the access token to send a tweet.
See this link for a flowchart of the full OAuth process.