XING oauth api error invalid oauth signature - oauth

I got a problem with the xing oauth api.
Currently this works:
Get a request token from xing
Redirect the client to authentificate at xing
Get the callback from xing
Now I have to get the access token from xing, using the oauth token and verifier.
I'm using the same code to generate the oauth signature for this like when I request the request token at step 1.
With this function, I generate the signature:
private function buildOauthSignature($httpMethod, $requestTokenUrl, $params) {
// Remove 'oauth_signature' if it's empty
if (empty($params['oauth_signature'])) {
unset($params['oauth_signature']);
}
$parts = array(
$httpMethod,
$requestTokenUrl,
$this->buildQuery($params)
);
$parts = $this->urlencode_rfc3986($parts);
$signatureBaseString = implode('&', $parts);
$keyParts = array(
$this->strategy['consumer_secret'],
""
);
$key = implode('&', $keyParts);
return base64_encode(hash_hmac('sha1', $signatureBaseString, $key, true));
}
Does someone know this?

Related

Outlook Office 365 : Refresh token failed to retrieve because "AADSTS70000" the provided value for the 'code' parameter is not valid

In below code I can retrieve refresh token successfully from email#company.com email addresses. However, when I try to login with email#outlook.com it doesn't give the refresh token instead it returns this response.
Response:
{
"error": "invalid_grant",
"error_description": "AADSTS70000: The provided value for the 'code' parameter is not valid. The code has expired.\r\nTrace ID: ...\r\nCorrelation ID: ...\r\nTimestamp: 2016-05-19 10:13:05Z",
"error_codes": [
70000
],
"timestamp": "2016-05-19 10:13:05Z",
"trace_id": "8cceb393-....",
"correlation_id": "5227de8...."
}
Code:
private async Task<string> GetRefreshRoken(string authCode, string onSuccessRedirectUri) {
var client = new HttpClient();
var parameters = new Dictionary<string, string>
{
{"client_id", _clientId},
{"client_secret", _clientSecret},
{"code",authCode }, // what retreived from //https://login.microsoftonline.com/common with authroization.
{"redirect_uri", onSuccessRedirectUri}, //http://localhost:27592/Home/Authorize
{"grant_type","authorization_code" }
};
var content = new FormUrlEncodedContent(parameters);
var response = await client.PostAsync("https://login.microsoftonline.com/common/oauth2/v2.0/token", content);
var tokensJsonString = await response.Content.ReadAsStringAsync();
dynamic token = Newtonsoft.Json.JsonConvert.DeserializeObject(tokensJsonString);
return token.refresh_token;
}
So I had googled with the error number and found http://www.matvelloso.com/2015/01/30/troubleshooting-common-azure-active-directory-errors/ page where the error describes:
Then I had changed my redirecting url to "http://localhost:27592/Home/Authorize/". Since I am using this https://dev.outlook.com/restapi/tutorial/dotnet tutorial as a reference , now I cannot login with any other account.
Is there any good approach to retrieve refresh tokens for outlook account?
For windows live id account, you will get error "The provided value for the 'code' parameter is not valid. The code has expired." when using the authorization code twice.
The correct way to refresh the token is using refresh token (v2.0 token reference > Refresh Token).
First, ensure you have declare the scope "offline_access".
Then, you will get the access_token when acquire the token using grant_type=code (the first time you acquire the token).
Next, you need to use grant_type=refresh_token to refresh your access token.

Scribe + Xing => Invalid OAuth signature

I'm trying to use scribe with XING and I'm always getting following answer:
Can't extract token and secret from this: '{"message":"Invalid OAuth signature","error_name":"INVALID_OAUTH_SIGNATURE"}'
I have a working login process, get back an oauth_token and an oauth_verifier and tried to to change the defaultly selected HMACSha1 Singature with a PlainText signature, but I'll always get the above mentioned result...
Any ideas on why this happens?
Using the default DefaultApi10a and XingApi from scribe always fails at the above mentioned step...
EDIT - Code
// Creating the service
// callback is needed to stop redirecting in the webview
OAuthService service = new ServiceBuilder()
.provider(XingApi.class)
.apiKey(apiKey)
.apiSecret(apiSecret)
.callback("http://www.xing.com")
.build();
Step 1: get request token + auth url
RequestToken requestToken = service.getRequestToken();
String authUrl = service.getAuthorizationUrl(requestToken );
Step 2: load the auth url in a webview + check the redirect url and cancel redirection based on callback
for example, redirection url look like following: http://www.xing.com?oauth_token=a2191ab84c9e0f85cf0c&oauth_verifier=4978
Step 3: extract oauth_token + oauth_verifier from returned url
String oauthToken = ...; // a2191ab84c9e0f85cf0c in the example
String oauthVerifier = ...; // 4978 in the example
Step 4: get access token => this fails
Token requestToken = new Token(oauthToken, oauthVerifier); // reusing the request token from above results in invalid request token answer from xing!
Verifier v = new Verifier(oauthVerifier);
Token accessToken = service.getAccessToken(requestToken, v);
Remove:
Token requestToken = new Token(oauthToken, oauthVerifier); // reusing the request token from above results in invalid request token answer from xing!
line from step 4.
You have to keep request token to retrieve access token using it and verifier (4 digits PIN) from Xing.
EDIT - code added:
OAuth10aService service = new ServiceBuilder()
.apiKey("44a4f9c1a9daa88f4da2")
.apiSecret("2fc8ca373dab772acc4de7ce22718f8fced6919c")
.callback("https://redirect.example.com")
.build(XingApi.instance());
final Token requestToken = service.getRequestToken();
System.out.println(service.getAuthorizationUrl(requestToken));
System.out.println("Paste the verifier here");
System.out.print(">>");
Scanner in = new Scanner(System.in);
Verifier verifier = new Verifier(in.nextLine());
System.out.println();
in.close();
// Trade the Request Token and Verfier for the Access Token
Token accessToken = service.getAccessToken(requestToken, verifier);
System.out.println("Got the Access Token! " + accessToken);

Google Oauth refresh Token

I'm trying to use Google Oauth to access Google Analytics Datas.
It's works fine except with token. The token expires after an hour and I don't know how to refresh it. There a line where there's "For simplicity of the example we only store the accessToken. If it expires use the refreshToken to get a fresh one" but I don't know how to…
Here's my code
$client_id = 'xxxxxxxxxx.apps.googleusercontent.com';
// From the APIs console
$client_secret = 'xxxxxxxxxxxxx';
// Url to your this page, must match the one in the APIs console
$redirect_uri = 'mylocalurl.php';
session_start();
include('GoogleAnalyticsAPI.class.php');
$ga = new GoogleAnalyticsAPI();
$ga->auth->setClientId($client_id);
$ga->auth->setClientSecret($client_secret);
$ga->auth->setRedirectUri($redirect_uri);
if (isset($_GET['force_oauth'])) {
$_SESSION['oauth_access_token'] = null;
}
/*
* Step 1: Check if we have an oAuth access token in our session
* If we've got $_GET['code'], move to the next step
*/
if (!isset($_SESSION['oauth_access_token']) && !isset($_GET['code'])) {
// Go get the url of the authentication page, redirect the client and go get that token!
$url = $ga->auth->buildAuthUrl();
header("Location: ".$url);
}
/*
* Step 2: Returning from the Google oAuth page, the access token should be in $_GET['code']
*/
if (!isset($_SESSION['oauth_access_token']) && isset($_GET['code'])) {
$auth = $ga->auth->getAccessToken($_GET['code']);
if ($auth['http_code'] == 200) {
$accessToken = $auth['access_token'];
$refreshToken = $auth['refresh_token'];
$tokenExpires = $auth['expires_in'];
$tokenCreated = time();
// For simplicity of the example we only store the accessToken
// If it expires use the refreshToken to get a fresh one
$_SESSION['oauth_access_token'] = $accessToken;
} else {
die("Sorry, something wend wrong retrieving the oAuth tokens");
}
}
Thanks
I am not sure of the details of doing this in PHP but there is an end point to request against for refreshing the access token.
The API end point is https://accounts.google.com/o/oauth2/token and the body of request should be something like
{
'refresh_token' => your_stored_refresh_token,
'client_id' => ENV['CLIENT_ID'],
'client_secret' => ENV['CLIENT_SECRET'],
'grant_type' => 'refresh_token'
}
If successful that request will return a fresh access token.

How to get a refresh_token with an auto-approved response?

I have the following code:
if (isset($_REQUEST['logout']))
{
unset($_SESSION['upload_token ']);
}
if (isset($_GET['code']))
{
$client->authenticate($_GET['code']);
$_SESSION['upload_token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['upload_token']) && $_SESSION['upload_token'])
{
$client->setAccessToken($_SESSION['upload_token']);
if ($client->isAccessTokenExpired())
{
echo "The access token is expired.<br>"; // Debug
$client->refreshToken(json_decode($_SESSION['upload_token']));
unset($_SESSION['upload_token']);
}
}
else
{
$authUrl = $client->createAuthUrl();
}
and am receiving the following error:
Uncaught exception 'Google_Auth_Exception' with message 'The OAuth 2.0 access token has expired, and a refresh token is not available. Refresh tokens are not returned for responses that were auto-approved.'
I am assuming I am getting this error because the response was auto-approved.
What should be changed?
UPDATE: I've tried adding this to my code:
$client->setAccessType("online");
$client->setApprovalPrompt("auto");
Based on this question. I still am receiving the same error of missing refresh token.
UPDATE: After kroikie's update, my code looks like the following:
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/drive");
$client->setAccessType("offline");
$client->setApprovalPrompt("auto");
$client->setApplicationName("Appraisal App");
$service = new Google_Service_Drive($client);
if (isset($_REQUEST['logout']))
{
unset($_SESSION['upload_token ']);
}
if (isset($_GET['code']))
{
$resp = $client->authenticate($_GET['code']);
$_SESSION['upload_token'] = $client->getAccessToken();
$array = get_object_vars(json_decode($resp));
// store and use $refreshToken to get new access tokens
$refreshToken = $array['refreshToken'];
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['upload_token']) && $_SESSION['upload_token'])
{
$client->setAccessToken($_SESSION['upload_token']);
if ($client->isAccessTokenExpired())
{
echo "The access token is expired. Let Raph know that you saw this.<br>";
$client->refreshToken($refreshToken);
unset($_SESSION['upload_token']);
}
}
else
{
$authUrl = $client->createAuthUrl();
}
Unfortunately, I still receive the same fatal error when the refresh token is needed.
When the access type is offline, an access token and a refresh token are returned when the user first grants data access. The access token can be used to access the user's data, and the refresh token is stored and used to get a new access token when the initial access token has expired.
So try using offline access type
$client->setAccessType('offline');
and use the refresh token to refresh the client's access token
// $refreshToken is retrieved from the response of the
// user's initial granting access
$client->refreshToken($refreshToken)
UPDATE:
To get the refresh token use something like:
if (isset($_GET['code'])) {
$resp = $client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
$array = get_object_vars(json_decode($resp));
// store and use $refreshToken to get new access tokens
$refreshToken = $array['refreshToken'];
}
Assuming you want to use the offline access type, you have two choices: either you force the approval prompt (so you never get an auto-approved response):
$client->setAccessType("offline");
$client->setApprovalPrompt("force");
Or you ignore the refresh token and simply get a new auto-approved authorization when your current token is expired. I never tested this but since no user action is required for approval, I assume it works.
You can read more about this here (Change #3: Server-side auto-approval): http://googlecode.blogspot.ca/2011/10/upcoming-changes-to-oauth-20-endpoint.html
Sometimes it's seems that the error is in the code, but in my case was not.
I had the same problem and tried all kind of solution, but the error was in the console.developers.google.com configuration.
I thought was not necessary to confirm the domain in the Credentials configuration.
So when i did it, so the code stopped giving the error.

Verify OAuth Token on Twitter

I'm storing the oauth info from Twitter in a Flash Cookie after the user goes though the oauth process. Twitter says that this token should only expire if Twitter or the user revokes the app's access.
Is there a call I can make to Twitter to verify that my stored token has not been revoked?
All API methods that require authentication will fail if the access token expires. However the specific method to verify who the user is and that the access token is still valid is GET account/verify_credentials
This question may be old, but this one is for the googlers (like myself).
Here is the call to twitter using Hammock:
RestClient rc = new RestClient {Method = WebMethod.Get};
RestRequest rr = new RestRequest();
rr.Path = "https://api.twitter.com/1/account/verify_credentials.json";
rc.Credentials = new OAuthCredentials
{
ConsumerKey = /* put your key here */,
ConsumerSecret = /* put your secret here */,
Token = /* user access token */,
TokenSecret = /* user access secret */,
Type = OAuthType.AccessToken
};
rc.BeginRequest(rr, IsTokenValid);
Here is the response:
public void IsTokenValid(RestRequest request, RestResponse response, object userState)
{
if(response.StatusCode == HttpStatusCode.OK)
{
var user = userState;
Helper.SaveSetting(Constants.TwitterAccess, user);
}
else
{
Dispatcher.BeginInvoke(() => MessageBox.Show("This application is no longer authenticated "))
}
}
I always borrow solutions from SO, this is my first attempt at giving back, albeit quite late to the question.
When debugging manually:
curl \
--insecure https://api.twitter.com/1/account/verify_credentials.json?oauth_access_token=YOUR_TOKEN
I am using TwitterOAuth API and here is the code based on the accepted answer.
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $twitter_oauth_token, $twitter_oauth_secret);
$content = $connection->get("account/verify_credentials");
if($connection->getLastHttpCode() == 200):
// Connection works fine.
else:
// Not working
endif;

Resources