Salesforce reports access using oauth as session id - web-services

I'm trying to get access to salesforce report data using oauth token. Some time ago it worked fine, I used the oauth token as session id.
...
URL remoteFile = new URL(instanceURL + "/" + reportId + "?export=1&enc=UTF-8&xf=csv");
URLConnection fStream = remoteFile.openConnection();
fStream.setRequestProperty("Cookie", "sid=" + accessToken);
...
But it doesn't work, everytime I try to access the url it returns an html page which corresponds to login page. Is there any way I can access report data (not meta-data) using the oauth access_token?
Thanks.

In order to use the token with such a URL you need to set the scope parameter to include web:
web Allows the ability to use the access_token on the Web.
The oAuth User Agent Flow documentation details where the scope parameter is specified.

Related

Generate Refresh Token for a GCP OAuth 2.0 Client ID

I am trying to access to an API that uses OAuth2 authentication with the Refresh Token grant.
So, to request this API, I need a Client Id, a Client Secret and a Refresh Token.
Using https://console.cloud.google.com/apis/credentials, I created a new OAuth 2.0 Client ID, which gives me a Client Id and a Client Secret.
But I struggle generating a Refresh Token.
By looking at this article, it looks like I need to execute the following POST query :
curl -X POST -d "code=[CODE]&client_id=[CLIENT_ID]&client_secret=[CLIENT_SECRET]&redirect_uri=[REDIRECT_URI]&grant_type=authorization_code" https://oauth2.googleapis.com/token
To retrieve the CODE parameter, I need to do another call to this URL : https://accounts.google.com/o/oauth2/v2/auth?scope=[SCOPE]&access_type=offline&include_granted_scopes=true&response_type=code&redirect_uri=[REDIRECT_URI]&client_id=[CLIENT_ID]
This call opens the Google login page.
However, I don't know how to log in with an OAuth 2.0 Client ID. I don't have an email linked to these credentials.
Am I following the correct steps to retrieve a Refresh Token in my use case, and if so, what am I missing here ?

Facebook Api Check Access Token Without Hardcoding App Secret

I'm building a manual login flow for my App which is integrating some facebook functionality.
I need to check when the current access_token of the user will expire.
The API documentary says I should do this call:
GET graph.facebook.com/debug_token?
input_token={token-to-inspect} &access_token={app-token-or-admin-token}
So I did this in C#:
Uri inspectAccessTokenUri = new Uri("http://graph.facebook.com/debug_token?input_token="+access_token+"&"); //IDK which value should have the last parameter
HttpWebRequest checkToken = (HttpWebRequest)WebRequest.Create(inspectAccessTokenUri);
var response = await checkToken.GetResponseAsync();
Stream stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string data = reader.ReadToEnd();
Debug.WriteLine(data);
The last parameter should be the app-token:
BUT: Of course I looked up how to get the app-token and facebook says:
Note that because this request uses your app secret, it must never be
made in client-side code or in an app binary that could be decompiled.
It is important that your app secret is never shared with anyone.
Therefore, this API call should only be made using server-side code.
(Facebook Graph API Documentation 1.1.16)
So my question: Can I check the token without the app-token or hardcoding the app-secret?
App secret is usually used by the server-side app, we don't use it in our UWP app, it could be decompiled.
Read the official doc about FB Graph Debug-Token, this can only be used when you debug your app, for example if you want to check the metadata about a given access token, after you publish your app, your code will not relay on it.
In an UWP app, we use WebAuthenticationBroker class to connect to OAuth providers such as Facebook, Flickr, Google, and Twitter. Maintenance is need during using OAuth connections. For example, expires information is included in the access token, when we use OAuth protocol for authentication and authorization, we need to refresh the access token after it expired.
Due to these conditions, you may reconsider what you can do in an UWP app and which API you should choose.
If the app-token is expired you will get a facebook response error. And you can catch this exception to deal with the situation you want. In this way you don't need to make a request with your app secret.
You can also use fb-uwp sdk that contains AccessTokenData for authenticated users

Generate an OAuth2 token in a view

Let's say I have an AngularJS application that consumes the REST API of a Django application.
The Django application has got a built-in OAuth2 provider that can be called to retrieve an access token and use the protected endpoints of the API. This provider is using django-oauth-toolkit.
Let's assume there is a registered client with "password" grant type, so that the end users only need to provide their credentials in the front-end in order to get an access token from the back-end.
At some point we want to add some support for social networks login and we decide to use python-social-auth (PSA) to that end. Here is the workflow I want to achieve:
The user logs in on Facebook from the front-end (via the Facebook SDK) and we get an access token back from the OAuth2 provider of Facebook.
We send the Facebook token to an endpoint of our REST API. This endpoint uses the Facebook token and django-social-auth to authenticate the user in our Django application (basically matching a Facebook account to a standard account within the app).
If the authentication succeeds, the API endpoint requests an access token from the OAuth2 provider for this newly authenticated user.
The Django access token is sent back to the front-end and can be used to access the REST API in exactly the same way that a regular user (i.e. logged in with his credentials) would do.
Now my problem is: how do I achieve step 3? I first thought I would register a separate OAuth2 client with Client Credentials Grant but then the generated token is not user-specific so it does not make sense. Another option is to use the TokenAuthentication from DRF but that would add too much complexity to my project. I already have an OAuth server and I don't want to set up a second token provider to circumvent my problem, unless this is the only solution.
I think my understanding of PSA and django-oauth-toolkit is not deep enough to find the best way of reaching my goal, but there must be a way. Help!
I managed to get something working using urllib2. I can't speak towards whether or not this is good practice, but I can successfully generate an OAuth2 token within a view.
Normally when I'd generate an access token with cURL, it'd look like this:
curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/
So we're tasked with making urllib2 accomplish this. After playing around for some bit, it is fairly straightforward.
import urllib, urlib2, base64, json
# Housekeeping
token_url = 'http://localhost:8000/auth/token/'
data = urllib.urlencode({'grant_type':'password', 'username':<username>, 'password':<password>})
authentication = base64.b64encode('%s:%s' % (<client_id>, <client_secret>))
# Down to Business
request = urllib2.Request(token_url, data)
request.add_header("Authorization", "Basic %s" % authentication)
access_credentials = urllib2.urlopen(request)
json_credentials = json.load(access_credentials)
I reiterate, I do not know if this is in bad practice and I have not looked into whether or not this causes any issues with Django. AFAIK this will do this trick (as it did for me).

Acquiring Long Lasting Facebook Token

Through Facebook's PHP SDK getting started guide it takes you through the process of initializing your app, creating a Login URL and then handling the call back data and doing a simple query.
In the documentation it says you can skip the initializing process providing an access token from 'some other means'.
$session = new FacebookSession('access token here');
Due to the lack of documentation I'm struggling on how I would define a scope before creating the login URL and then use the call back data to extract the access token.
This tutorial will help you get started with using the Facebook PHP SDK to log a user in.
Basically, you need to setup your application first and use the FacebookRedirectLoginHelper to create the login URL:
FacebookSession::setDefaultApplication( 'xxx','yyy' );
// login helper with redirect_uri
$helper = new FacebookRedirectLoginHelper( 'http://yourwebsite.com/app/' );
// show login url, scope is array of permissions
echo 'Login';

Retrieving Linkedin Group discussion posts using ColdFusion

I have been requested by a client to pull the latest posts from their LinkedIn group to one of our website pages.
I am developing using ColdFusion 9 and have been researching this for quite a few days now and decided to post my query here in the hopes that someone will be able to help me out.
I can get to the point where I have a requestToken. My understanding is that I now need to sign the request token to get the accessToken. My problem is that I need to do this behind-the-scenes. However, all the examples that I can find are redirecting the front-end user to the authorisation url to allow the user to authenticate, but I don't want the user to authenticate, I want to authenticate server-side instead.
I am trying to use the Scribe Java wrapper library. Below is the code that I have so far which gets the requestToken (as well as the authorisation url). I need someone to point me in the right direction to sign the token on the server-side code so that I can make the necessary calls to consume the Groups API (e.g. http://api.linkedin.com/v1/groups/{id}/posts?count=5&start=1)
<cfscript>
var l = {};
//The LinkedIn public and private keys for application
l.oauth_consumer_key = "[My public key]";
l.oauth_sign_key = "[My secret key]";
l.serviceBuilder = CreateObject("java","org.scribe.builder.ServiceBuilder");
l.LinkedInApiClass = CreateObject("java", "org.scribe.builder.api.LinkedInApi").getClass();
l.service = l.serviceBuilder.provider(l.LinkedInApiClass).apiKey(l.oauth_consumer_key).apiSecret(l.oauth_sign_key).callback("[My callback url]").build();
l.requestToken = l.service.getRequestToken();
l.authUrl = l.service.getAuthorizationUrl(l.requestToken);
// I NEED TO DEFINE WHAT TO DO AT THIS POINT TO SIGN THE REQUEST SERVER SIDE
...
...
</cfscript>
Kirsten is technically correct - Linked In Api's require user authentication. It's annoying because you need to authenticate to even retrieve group posts.
However there are ways round it.
With scribe you can manually create an access token. So what I would do is create a dummy user account on Linked In, authenticate that user as normal and save the returned signed credentials on your database, which you can then use to create the token:
var accessToken = createObject("java", "org.scribe.model.Token").init(
"singedTokenStringReturnBackFromLinkedIn",
"singedSecretStringReturnBackFromLinkedIn",
"oauth_token=singedTokenStringReturnBackFromLinkedIn&oauth_token_secret=singedSecretStringReturnBackFromLinkedIn&oauth_expires_in=0&oauth_authorization_expires_in=0"
);
You can then skip the authenticate part and call the api allowing you to display the group posts without the current user having to sign in:
var req = createObject("java", "org.scribe.model.OAuthRequest").init(
createObject("java", "org.scribe.model.Verb").GET,
"http://api.linkedin.com/v1/groups/123456/posts"
);
oAuthService.signRequest(accessToken, req);
I have no idea if this would violate Linked In's T&C though.
OAuth authentication is designed for the user to give their permission to the application via a login on the site (in this case LinkedIn). It is not designed for you to automatically have the user grant permission for your application.
In order to get an access token to use the LinkedIn APIs, you have to include the part of the authentication flow that sends the user to LinkedIn to give your application permission to act on their behalf, at which point you can retrieve a verifier token either via PIN (which the user inputs) or via a callback to your application.
In short, there is no way to "authenticate server-side" without having the user interact with the LinkedIn site.