Scribe + Xing => Invalid OAuth signature - oauth

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);

Related

Set url for GraphApi B2C login

I need to query the Graph API to get the username in the claims.
I've implemented something based on what I've found on the net, but I keep getting 403 Forbidden, from Graph API.
Can anyone help me with this?
This is my code:
var clientId = "clientId";
var clientSecret = "clienSecret";
var tenant = "tenantName";
var userObjectId = claimsPrincipal.Claims.Where(i => i.Type == "http://schemas.microsoft.com/identity/claims/objectidentifier").FirstOrDefault().Value;
var aadGraphVersion = "api-version=1.6";
var query = "/users/" + userObjectId;
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/" + tenant);
// The ClientCredential is where you pass in your client_id and client_secret, which are
// provided to Azure AD in order to receive an access_token using the app's identity.
ClientCredential credential = new ClientCredential(clientId, clientSecret);
// First, use ADAL to acquire a token using the app's identity (the credential)
// The first parameter is the resource we want an access_token for; in this case, the Graph API.
AuthenticationResult result = await authContext.AcquireTokenAsync("https://graph.windows.net", credential);
// For B2C user management, be sure to use the Azure AD Graph API for now.
HttpClient http = new HttpClient();
//var url = "https://graph.windows.net/" + tenant + "/users/" + userObjectId + "/?api-version=1.6";
//var url = graphResource + "tenant" + "/users/" + userObjectId + "/?api-version=1.6";
string url = "https://graph.windows.net/" + tenant + "/users/" + userObjectId + "?" + aadGraphVersion;
//url += "&" + query;
// Append the access token for the Graph API to the Authorization header of the request, using the Bearer scheme.
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
HttpResponseMessage response = await http.SendAsync(request);
if (!response.IsSuccessStatusCode)
{
string error = await response.Content.ReadAsStringAsync();
object formatted = JsonConvert.DeserializeObject(error);
throw new WebException("Error Calling the Graph API: \n" + JsonConvert.SerializeObject(formatted, Formatting.Indented));
}
I think I have a problem with the URL that is not set correctly. The token is correct, I got it ok with the credentials.
I do think it is an issue with the URL. You are getting this error as you have provided user read permissions to your registered application. Please make sure that -
You go to Application registrations menu on your tenant
Select "Required Permissions" menu and click on Windows Azure Active Directory
In the "Enable Access" menu select "Read Directory Data" permissions under Application Permissions section and click save.
Once saved on "Required Permissions" menu click on "Grant Permissions" button to provide the consent.
You may need to select other options like "Read and Write Directory Data" if you wish to provide your application to create/update/delete users.

Spring Security and Angular 5

Right now I'm sending username and password through header from my angular 5 app after successful login to access spring rest api. After Successful I'm getting unique sessionId from spring in response can I use that ID instead of credentials to authenticate
angular code
let d=localStorage.getItem('currentUser');
let headers = new Headers();
var user=JSON.parse(d);
headers.append('Accept', 'application/json');
// creating base64 encoded String from user name and password
var base64Credential: string = btoa(user.principal.username+ ':' + user.principal.password);
headers.append("Authorization", "Basic " + base64Credential);
let options = new RequestOptions({ headers: headers
});
var self = this;
self.greeting = {id:'', content:''};
http.get(this.url,options).map(response => self.greeting = response.json);
You can use jwt token for this.
Store the sessionId in localStorage or a cookie.
Send it inside the request header in each and every request (use httpInteceptor for this)
https://medium.com/#ryanchenkie_40935/angular-authentication-using-the-http-client-and-http-interceptors-2f9d1540eb8
In the Java application, add filter to all the requests, which need to be protected.

Getting Gmail API access and ID token, but refresh token is NULL

Following https://developers.google.com/identity/sign-in/web/server-side-flow After getting the authorization code from JavaScript, and passing it to the server side, we indeed get an access token (and an ID token), but not the required refresh token.
There are many posts around but could not solve it yet.
Any suggestion how to get the refresh token?
thanks!
private String getResponseToken(GoogleClientSecrets clientSecrets,
String authCode) throws IOException {
try {
GoogleTokenResponse tokenResponse =
new GoogleAuthorizationCodeTokenRequest(
new NetHttpTransport(),
JacksonFactory.getDefaultInstance(),
"https://www.googleapis.com/oauth2/v4/token",
// "https://accounts.google.com/o/oauth2/token",
clientSecrets.getDetails().getClientId(),
clientSecrets.getDetails().getClientSecret(),
authCode, //NOTE: was received from JavaScript client
"postmessage" //TODO: what's this?
).execute();
String accessToken = tokenResponse.getAccessToken();
String idToken = tokenResponse.getIdToken();
//TODO: not getting a refresh token... why?!
String refreshToken = tokenResponse.getRefreshToken();
Boolean hasRefreshToken = new Boolean(!(refreshToken == null));
LOGGER.warn("received refresh token: {}", hasRefreshToken);
LOGGER.debug("accessToken: {}, refreshToken: {}, idToken: {}", accessToken, refreshToken, idToken);
return accessToken;
}catch (TokenResponseException tre){...}
Gmail API only gives the refresh token the first time you ask for the users permission. (At least this is what happens to me).
Go to: https://myaccount.google.com/permissions?pli=1, remove the authorization to your app and run your code. You should receive the refresh token.
you should add the
AccessType = "offline"
You need to call the function
new GoogleAuthorizationCodeRequestUrl(...).setAccessType("offline")
or another syntax:
var authReq = new GoogleAuthorizationCodeRequestUrl(new Uri(GoogleAuthConsts.AuthorizationUrl)) {
RedirectUri = Callback,
ClientId = ClientId,
AccessType = "offline",
Scope = string.Join(" ", new[] { Scopes... }),
ApprovalPrompt = "force"
};
in Fiddler you should see the following request:
https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/webmasters&redirect_uri=http://mywebsite.com/google/scapi/callback/&response_type=code&client_id=xxx&access_type=offline
see also here
More details about setAccessType can be found here
after finding how to use the Google APIs at the backend (documentation is somewhat partial..), the issue was fixed at the FrontEnd side by tweaking a parameter:
grantOfflineAccess({
- prompt: 'select_account'
+ prompt: 'consent'
HTH

XING oauth api error invalid oauth signature

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?

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.

Resources