Extend Facebook Token - c#

I am using the Microsoft.AspNet.Mvc.Facebook NuGet package. I would like to exchange a regular token for the extended access token (the one that replaced the offline_access permission).
From Googling around I found the URL should be in this format:
https://graph.facebook.com/oauth/access_token?
client_id=[APP_ID]&
client_secret=[APP_SECRET]&
grant_type=fb_exchange_token&
fb_exchange_token=[EXISTING_ACCESS_TOKEN]
So I use the following code:
var longToken = await context.Client.PostTaskAsync("/oauth/access_token",
new
{
client_id = fbApp.AppId,
client_secret = fbApp.AppSecret,
grant_type = "fb_exchange_token",
fb_exchange_token = context.AccessToken
});
This returns a null. No error or anything. Just a null value.
Edit: Also tried the following, which also did not work. But a GET seems more logical than a POST anyway.
dynamic result = context.Client.Get("oauth/access_token",
new
{
client_id = fbApp.AppId,
client_secret = fbApp.AppSecret,
grant_type = "fb_exchange_token",
fb_exchange_token = context.AccessToken
});
var longToken = result.access_token as string;

I have successfully done this as a GET request, not a POST :) Just put the necessary parameters into the URL and request it as a GET request and the response returns the long term access token.
EDIT
When you get the result from this, you should parse the query string first (am not sure in C# but maybe you could use this link: http://msdn.microsoft.com/en-us/library/ms150046(v=vs.110).aspx).
After that try to get the access_token property and I got it right on my end. I was doing it in node.js though, but essentially the same flow.

Related

Generate user token from AuthenticationContext

I am trying to generate a user token for the purpose of testing an API that requires one. The tests run automatically. I have the following code example, but it seems to be out of date
Uri endpointUri = new Uri("my endpoint");
string resource = "my rid";
string clientId = "my client id";
PlatformParameters parameters = new PlatformParameters(PromptBehavior.Auto);
string authContextURL = "my url";
var authenticationContext = new AuthenticationContext(authContextURL, new TokenCache());
// Here you are sending a request to AAD with the user credentials.
AuthenticationResult result = await authenticationContext.AcquireTokenAsync(resource: resource, clientId: clientId, redirectUri: endpointUri, parameters);
// If the request succeeded you can get the user access token as follows.
return result.AccessToken;
The reason I believe it to be out of date is that PlatformParameters now requires 2 parameters, and I cannot find what the 2nd parameter should be by default.
My question is, how can I create a user-context token to use in testing my API from the test code?
EDIT
According to this answer, PlatformParameters with 1 param is for .netframework, whereas I am using .net 6
Still looking to any leads there may be!

Find a User by Email Address

I'm trying find out if an email address is already taken in my Azure AD B2C directory.
var token = await this.GetTokenAsync();
var client = new HttpClient();
var id = HttpUtility.UrlEncode("adrian_mydomain.com#EXT##xxxxxxxxx.onmicrosoft.com");
////var id = HttpUtility.UrlEncode("adrian#mydomain.com"); // This also fails.
////var id = HttpUtility.UrlEncode("adrian_mydomain.com#EXT#"); // This also fails.
////var id = "xxxx-xxxx-xxxxxxxx-xxxxxxxxxx"; // This also fails (user object id).
var resource = $"{this.graphConfig.GraphUri}/{this.graphConfig.Tenant}/users/{id}?api-version=1.6";
//// This line below works, it returns all the users, so I do know the token is good and the resource URI is valid, etc.
////var resource = $"{this.graphConfig.GraphUri}/{this.graphConfig.Tenant}/users?api-version=1.6";
var request = new HttpRequestMessage(HttpMethod.Get, resource);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
I'm encoding my email address in the same way that I see my email address encoded when I get all users. I have a feeling I'm close, if it is even possible to query by email address.
Currently all the things I've tried either return a 400 or a 404. Does anyone know if there is a way to query by email address (sign in name)?
EDIT
On a similar theme, I'm also trying a query to change a user's password to no avail. I figure if I can get the query working for one, I can get it working on the other.
Since it is a odata, you can query using odata syntax. Odata syntax here
var queryString = HttpUtility.ParseQueryString(string.Empty);
queryString["api-version"] = "1.6";
queryString["$filter"] = "signInNames/any(x:x/value eq 'paule#test.in')";
string url = "https://graph.windows.net/" + tenant + "/users"+ "?" + queryString;
$filter did the trick
queryString["$filter"] = "signInNames/any(x:x/value eq 'paule#test.co.uk')";
Take a look at the B2C.exe implementation, first get that working:
https://azure.microsoft.com/nl-nl/documentation/articles/active-directory-b2c-devquickstarts-graph-dotnet/
You will notice that the user is referenced by GUID or by UPN, not by email!
Emails are in the collection signInNames
To query on email address, you will need to specify a filter:
https://msdn.microsoft.com/en-us/library/azure/ad/graph/api/users-operations#GetUsers
Start with the GetUsers(to get all users), then update password and last the filter.
signInNames isn't the only place that emails are stored. It could also be userPrincipalName or otherMails. You'll want to use the following query to search all possible fields for an email.
/users?api-version=1.6&$filter=otherMails/any(x:x eq '{email}') or userPrincipalName eq '{email}' or signInNames/any(x:x/value eq '{email}')
I'm also trying to find a user by their login/email address.
Here's my (obfuscated XXXX) query string:
"https://graph.windows.net/XXXX.onmicrosoft.com/users?api-version=1.6&$filter=signInNames/any(x: x/value eq 'dd.rrr#XXXX.com')"
It doesn't error, but doesn't find the user (whom I know to exist, because GetAllUsers finds it).
However, looking at the user details, I can see:
"showInAddressList": null,
"signInNames": [],
"sipProxyAddress": null,
Could this be a clue as to why search doesn't work?
How can a user NOT have a signInName?

Malformed access token 190 error

when trying to redirect to gain a new access token an error occurred saying :
(OAuthException - #190) Malformed access token AQClEC8NbS1tbO4_HzqqZwVy2Inrk5I7vBpszPDPN0dVOV0ekurwNEpqzlWe2hQzl2KNZ5BwiSvL16bDPhR5IxFeJXEXBdM67uky7iwKbYKIVoRF__iyayyXBgcIp939gEZNtCUxyO4ZKZHQ9xmEwDstaOgq_bAvtygwv3YUeEYD9wftsytMZYwVxDO7rjq-2i3-XCYj643-6_1yKZ0dDahAB00iBqJqw1xiZ-l1kzStmA_pwMwO5dtBHZozp-L2hp0JEeTL0Fhc5CG1zbJ8Om6kyKBWyZuc0AtOrdSjgcBQBv9hQSF5pwsMZvFDGcjiwSc
what possibly could be the problem i am doing this method to redirect :
string redirecturl = #"https://graph.facebook.com/oauth/authorize?client_id=507061112747022&redirect_uri=http://localhost:63695/FacebookChatApi/Default.aspx";
Response.Redirect(redirecturl);
and i am reading the access token as follow :
string accessToken=Request["code"];
var client = new FacebookClient(accessToken); // here is where the error occurred
Is this the right method to get a client access token ?
why this error is occurring when reading the code value
according to Facebook Debug tool, your token is not a Token but a URL instead: https://developers.facebook.com/tools/debug/og/object?q=AQClEC8NbS1tbO4_HzqqZwVy2Inrk5I7vBpszPDPN0dVOV0ekurwNEpqzlWe2hQzl2KNZ5BwiSvL16bDPhR5IxFeJXEXBdM67uky7iwKbYKIVoRF__iyayyXBgcIp939gEZNtCUxyO4ZKZHQ9xmEwDstaOgq_bAvtygwv3YUeEYD9wftsytMZYwVxDO7rjq
I'm not sure who you get it, and why you get it instead of access token - you did not show enough code. From what I saw, I believe you generate your redirecturl incorrectly. Below is a piece of code from one of my project - please try it and let me know if it works for you:
// 1. redirect user to the login page:
var redirectUri = "http://localhost:63695/FacebookChatApi/Default.aspx";
var service = new FacebookClient();
var loginUrl = service.GetLoginUrl(new {
client_id = ConfigurationProvider.FacebookAppId,
client_secret = ConfigurationProvider.FacebookAppSecret,
redirect_uri = redirectUri,
response_type = "code",
scope = "manage_pages, publish_actions, user_photos, publish_stream" // Add other permissions as needed
});
Response.Redirect(loginUrl);
// 2. And when user authorizes, get the access token
// NOTE: code executes on FacebookChatApi/Default.aspx page
var redirectUri = "http://localhost:63695/FacebookChatApi/Default.aspx"; // must be the same as in the login call!
var fb = new FacebookClient();
dynamic result = fb.Post("oauth/access_token", new
{
client_id = ConfigurationProvider.FacebookAppId,
client_secret = ConfigurationProvider.FacebookAppSecret,
redirect_uri = redirectUri,
code = code
});
var accessToken = result.access_token;

Check User Tokens are valid or not using Twitter Api

I have a Asp.Net application that will post tweets in twitter.
I'm using Twitterizer2 for doing this.
First time when the user uses the application, he will be redirected to twitter for authentication.
And then the user-token will be stored in my application , so that the user will never be asked again to login to twitter.
This is working fine.
Now i want to validate the user-tokens before posting (ie valid token or not) . Is there any way to do this validation?
You can make a call to the Verify Credentials API
Make an authenticated call to
https://api.twitter.com/1/account/verify_credentials.json
It will respond with HTTP 200 OK if the tokens are correct - or 401 if they are not.
MoH's code didn't work for me. Here's what I did:
public bool IsTwitterAccessTokenValid(String access_token, String token_secret)
{
var token = new Twitterizer.OAuthTokens();
token.ConsumerKey = this.TwitterConsumerKey;
token.ConsumerSecret = this.TwitterConsumerSecret;
token.AccessToken = access_token;
token.AccessTokenSecret = token_secret;
var twitterResponse = TwitterAccount.VerifyCredentials(token);
return (twitterResponse.Result == RequestResult.Success);
}
I found out the code for validating tokens in another question.
The Twitterizer Api itself had the Methods to validate the User tokens.
The code is as follows:
Twitterizer.OAuthTokens token = new Twitterizer.OAuthTokens();
token.ConsumerKey = this.AppId;
token.ConsumerSecret = this.AppSecret;
token.AccessToken = userToken;
token.AccessTokenSecret = userSecret;
Twitterizer.TwitterResponse<Twitterizer.TwitterUser> response =
Twitterizer.TwitterAccount.VerifyCredentials(token);
if (String.IsNullOrEmpty(response.ErrorMessage))
{
//This is a valid token
}
else
{
//Invalid token
}

Getting OAuth2 refresh token

I'm trying to use Google's Calendar API to demo out an OAuth2 integration that we'll need to do with another third party. I'm using the DotNetOpenAuth library, and I've been able to get the initial redirect to Google for the Allow / Deny prompt and get the authorization code back.
I now need to get the access token and refresh token, but I only seem to get an access token back, refresh token is null.
This is my controller action method where Google redirects back to after the user Accepts or Denies:
public ActionResult ProcessResponse(string state, string code, string error)
{
var oAuthClient =
new WebServerClient(
new AuthorizationServerDescription
{
TokenEndpoint = new Uri("https://accounts.google.com/o/oauth2/token"),
AuthorizationEndpoint = new Uri("https://accounts.google.com/o/oauth2/auth"),
ProtocolVersion = ProtocolVersion.V20
},
_applicationId,
_secret)
{
AuthorizationTracker = new TokenManager()
};
var authState = oAuthClient.ProcessUserAuthorization();
var accessToken = authState.AccessToken;
var refreshToken = authState.RefreshToken;
return View(new[] { accessToken, refreshToken });
}
Any ideas?
EDIT:
To get the authorization code, I setup the oAuthClient identically to what I did above, and use this method:
oAuthClient.RequestUserAuthorization(new[] { "https://www.googleapis.com/auth/calendar" }, returnUrl);
I had a similar problem, and solved mine by hand-coding the HttpRequest and HttpResponse handling. See code at: https://stackoverflow.com/a/11361759/29156

Categories

Resources