Facebook4J support for exchanging access-tokens - facebook

I'm looking for a way to exchange short-lived access tokens for long-lived access tokens in our backend as described by Facebook here. How to do this with facebook4j?

I have done something like this to exchange old token for new token:
private AccessToken refreshToken(Facebook facebook, AccessToken currentToken) throws Exception {
String clientId = configuration.getString(ConfigurationKeys.SOCIAL_FACEBOOK_CLIENTID);
String clientSecret = configuration.getString(ConfigurationKeys.SOCIAL_FACEBOOK_CLIENTSECRET);
Map<String, String> params = new HashMap<String, String>();
params.put("client_id", clientId);
params.put("client_secret", clientSecret);
params.put("grant_type", "fb_exchange_token");
params.put("fb_exchange_token", currentToken.getToken());
RawAPIResponse apiResponse = facebook.callGetAPI("/oauth/access_token", params);
String response = apiResponse.asString();
AccessToken newAccessToken = new AccessToken(response);
facebook.setOAuthAccessToken(newAccessToken);
return newAccessToken;
}
I think this can be done after each login so the access token is refreshed even if it still valid - you will just get newer token with 60 days of validity.
What do you think?

I am extending the Facebook class. The method they provided don't work. So I wrote another function which does gives a long lived token but it's somehow invalid ( I tried testing the new token with token_debug and tried to generate client_code with it)! I will update you if I get to work it out. If you can solve it, please update me.
Please remember I didn't clean up the code as I am still writing on it.
public function GetExtendedAccessToken()
{
//global $CONFIGURATIONS;
//$info=$this->api($path,'GET',$args);//doesn't work as api overrides method to post
$string=file_get_contents("https://graph.facebook.com/oauth/access_token?client_id=".$this->getAppId()
."&client_secret=".$this->getAppSecret()
."&fb_exchange_token=".$this->getAccessToken()
."&grant_type=fb_exchange_token"
."&redirect_uri=".$redirectUri);
var_dump($string);
$tokenInfo=explode('&',$string);
$exAccessToken=str_replace('access_token=', '', $tokenInfo[0]);
$expiresAt=str_replace('expires=', '', $tokenInfo[1]);
echo "expires in ". (time()-$expiresAt);
var_dump($exAccessToken);
return $exAccessToken;
}
It works now. Some times I get an error for not providing redirect_uri.

Related

Pass a token via the addition of a URL query parameter with "token=tokenvalue." in Azure Media Service not working

Trying to stream a video from Azure Media Service into a Xamarin.Form application.
The asset is protected with a JWT token.
I use the following code to generate the token:
private string GetJWT(string PrimaryKey) {
var tokenSigningKey = new SymmetricSecurityKey(Convert.FromBase64String(PrimaryKey));
SigningCredentials cred = new SigningCredentials(tokenSigningKey, SecurityAlgorithms.HmacSha256);
JwtSecurityToken token = new JwtSecurityToken(
issuer: "xxx",
audience: "yyy",
claims: null,
notBefore: DateTime.Now.AddMinutes(-5),
expires: DateTime.Now.AddMinutes(60),
signingCredentials: cred);
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
return handler.WriteToken(token);
}
The URI for the asset is like : https://xxx.streaming.media.azure.net/12222-1565-232323-a5b8-c10e148273ae/Test.ism/manifest(format=m3u8-cmaf,encryption=cbc)
If I use Azure Media Player (https://ampdemo.azureedge.net) to test the URI and the AES token, it works fine. So I guess there is no problem with the token itself...
The documentation (https://learn.microsoft.com/en-us/azure/media-services/latest/security-pass-authentication-tokens-how-to#pass-a-token-via-the-addition-of-a-url-query-parameter-with-tokentokenvalue) says that the following code should work to send the token directly with the url.
I need to do this as with Xamarin.Forms and MediaElement, I can't send the token in a header request. So I need the querystring option...
string armoredAuthToken = System.Web.HttpUtility.UrlEncode(authToken);
string uriWithTokenParameter = string.Format("{0}&token={1}", keyDeliveryServiceUri.AbsoluteUri, armoredAuthToken);
Uri keyDeliveryUrlWithTokenParameter = new Uri(uriWithTokenParameter);
player.Source = keyDeliveryUrlWithTokenParameter; (player is a MediaElement control)
But the video is never loaded.
In my opinion there is an error, it should be {0}?token={1} instead of {0}&token={1}.
But that doesn't work neither.
If I test with VLC the https://xxx.streaming.media.azure.net/12222-1565-232323-a5b8-c10e148273ae/Test.ism/manifest(format=m3u8-cmaf,encryption=cbc)?token=zzzzz, it doesn't work neither.
I presume there is a problem with token in the querystring, as if Azure can't read it.

How to obtain an access token within a Keycloak SPI?

Use case:
From inside a EventListenerProvider on an event I want to make an authenticated REST call to one of our keycloak secured service. For this I need a token.
First I just test printing the token to check whether it is succeeded.
public void onEvent(final Event event) {
Keycloak k = Keycloak.getInstance("http://localhost:8080/auth", "myrealm", "myemail#gmail.com", "password", "myclient");
AccessTokenResponse t = k.tokenManager().getAccessToken();
logger.info(t.getSessionState());
logger.info(t.getToken());
}
Unfortunatly both the session_state and token is NULL.
All the data are correct, the url,the realm..etc. Otherwise we would know about that. Keycloak doesnt log anything just silently returns null.
On the top of that I can use the above code from anywhere else and it works! I can use it from a plain java main() method and still works. Getting token by hand via postman also works.
What is wrong with the Keycloak Provider? How can I get an accesstoken for a particular user?
You can use the following example to create a AccessToken:
public String getAccessToken(UserModel userModel, KeycloakSession keycloakSession) {
KeycloakContext keycloakContext = keycloakSession.getContext();
AccessToken token = new AccessToken();
token.subject(userModel.getId());
token.issuer(Urls.realmIssuer(keycloakContext.getUri().getBaseUri(), keycloakContext.getRealm().getName()));
token.issuedNow();
token.expiration((int) (token.getIat() + 60L)); //Lifetime of 60 seconds
KeyWrapper key = keycloakSession.keys().getActiveKey(keycloakContext.getRealm(), KeyUse.SIG, "RS256");
return new JWSBuilder().kid(key.getKid()).type("JWT").jsonContent(token).sign(new AsymmetricSignatureSignerContext(key));
}
Note that you also need to specify <module name="org.keycloak.keycloak-services"/> in your jboss-deployment-structure.

eBay REST API Get Offers Authetication Error

I am attempting to get eBay product IDs using the GetOffers request by sending it a product SKU.
My code is below, the problem I am currently having is that when I try to test this code is returns a 401 unauthorized. It's not returning any specific error code or anything descriptive.
I know my access token is valid I can't find any good examples on how to use this request.
public string getEbayOffers(string sku)
{
HttpResponseMessage response;
string accessToken = "tokenhere";
string param = Convert.ToBase64String(Encoding.ASCII.GetBytes(accessToken));
string url = $"sell/inventory/v1/offer?sku={sku}";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.ebay.com/");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", param);
response = client.GetAsync(url).Result;
}
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsStringAsync().Result;
}
return null;
}
No need to convert your token to base64. The correct format should be "Bearer YOUR_USER_TOKEN". Replace YOUR_USER_TOKEN with your own token string.
Access token should be enough for getting offers but maybe you can try to use user token if above doesn't work.

Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request

My facebook login url
https://graph.facebook.com/v2.3/oauth/access_token?client_id=1105783646200782&redirect_uri=http://petmilyapp.com/test3.php&client_secret=69389226fe79865b3ab557f17e8e54ad&code=AQCgR8S7oM2eZWQVP_U8ieBmPcEy_ztQ3LGbcYDsAGWnn0343kOyS6t6_n8AWGggUbF7ib9pU-q4Nr2QBewRMFLe_MROdzpgvhdYwRaFZlr6geC9pESjUrGGNHxEqkjwftVBbmGd4_QOkZAFNJnJQYeW8hvyHhfgiY-W02HTczpMa3PIIGL6OGO0qoRN8KWkBi84qMBNCQ_OF84u-r9kfeoYML9_BUVJf5LCuzIBYBsQmbrNHBwiYKKHyo3MaUC_k2WRirhFk1mSPfWwwihw3U04hIxYX_KG6qSwZ1wmlp3mhYMdP4FuA2VYIg8i7WwZQxyYzonoDyuH6ZuYq_Rb6qi6
response error
message: "Error validating verification code. Please make sure your redirect_uri is identical to the one you used in the OAuth dialog request"
question
What problem in my url?
All param is getted facebook dev (my app).
I know maybe its too late but I just wanted to comment. If you still having this issue, make sure that you have same FacebookCallBack method name everywhere. I mean, for instance I have an External Login function which returns ;
https://www.facebook.com/dialog/oauth?client_id=" + FB_APP_ID + "&redirect_uri=" + System.Net.WebUtility.UrlEncode(pageUrl + "account/**FacebookLoginCallback**?returnUrl=%2F").Replace("%3F", "&") + "&scope=email&enforce_https=1
and also I have a FacebookLoginCallback method which has exactly the same name with I have above. ("account/FacebookLoginCallback?....")
[HttpGet("**FacebookLoginCallback**")]
public async Task<IActionResult> **FacebookLoginCallback**(string code, string returnUrl)
{
try
{
var myUrl = new Uri(HttpContext.Request.GetDisplayUrl()).GetLeftPart(UriPartial.Authority);
var pageUrl = new UriBuilder(myUrl);
var result = (IDictionary<string, object>)fb.Get("oauth/access_token", new
{
client_id = FB_APP_ID,
client_secret = FB_APP_SECRET,
redirect_uri = pageUrl.Uri.AbsoluteUri.TrimEnd('/') + Url.Action("**FacebookLoginCallback**", "Account", new { returnUrl = returnUrl }),
code = code
});
}
......
}
Please double check your variable/function names if you have those in your url.
Happy Coding
First, both redirect_uri paramaters to authorize and access_token must match.

IdentityServer3 Guidance Needed

I have a scenario where a client has an OpenIdConnect (OIDC) token in their possession. The OIDC was issued from an external OIDC provider, I am not the OIDC provider, just the downstream consumer of it.
The goal is for the client to exchange said OIDC Token, for temporary credentials, or an accesstoken, which will then give them api access to more specific resources.
In my case, the OIDC represents a user. The client, has a ClientId/Secret, which is used to establish service-2-service trust. In the end I would like to have something that looks a lot like the CustomGrant token Request.
static TokenResponse GetCustomGrantToken()
{
var client = new TokenClient(
token_endpoint,
"custom_grant_client",
"cd19ac6f-3bfa-4577-9579-da32fd15788a");
var customParams = new Dictionary<string, string>
{
{ "some_custom_parameter", "some_value" }
};
var result = client.RequestCustomGrantAsync("custom", "read", customParams).Result;
return result;
}
where my customParams would contain the OIDC to my user.
Problem: I can get a token back from the GetCustomGrantToken call, however a follow up Webapi call fails to pass Authorization. i.e. Identity.isAuthenticated is false.
The it all works fine if I get a clientcredential token.
static TokenResponse GetClientToken()
{
var client = new TokenClient(
token_endpoint,
"silicon",
"F621F470-9731-4A25-80EF-67A6F7C5F4B8");
return client.RequestClientCredentialsAsync("api1").Result;
}
Had the CustomGrantToken worked I would have put my users account info in the claims, thus giving me context in the subsequent WebApi calls.
Any direction would be appreciated.