Authentication and authorization is always a key challenge when connecting different systems. It can be simple when having all systems connected to the same Identity Provider (IdP), but it can be challenging if not.
With the rise of cloud-based applications different approaches have been established. The majority of enterprises uses SAML when/where possible. In most other cases services like OpenID or OAuth are used. In this post we’ll focus on the latter – OAuth as of version 2 – and how a Java app can be connected to Salesforce App Cloud using the widely spread Scribe library.
OAuth in a simple nutshell
You’ll find lots of descriptions about what OAuth2 is and how it works in the web, as it has been originally established in 2006. So I’m not going to explain it in depth. If you are already familiar with it – feel free to scroll down to the OAuth2 with Scribe section.
OAuth2 is basically a mechanism that allows systems to interact on behalf of a user – without exposing real credentials like username/password to those systems.
Think about the following situation:
- You hire a cleaning company for your house which should clean certain parts of it.
- You don’t want to give them your main key (aka username/password).
- Instead the cleaner-on-duty should get a temporary key that allows him to enter specific rooms.
So let’s translate this for OAuth2.
- You hire a cleaning company for your house which should clean certain parts of it (== connect your account to the 3rd party account).
- You give the cleaning company an id (clientId) and a secret keyword (clientSecret).
- A cleaner approaches the front door with the secret password. You’re going to authenticate him via the secret password.
- Based on his authentication he’s now getting a temporary key (accessToken) that allows him to enter specific rooms.
- He can now enter the house whenever needed, until you revoke the temporary key.
This example is quite simplified, but should give you a brief overview about the involved mechanisms. As said – Google is your friend. A very good reference is also the official documentation. Lets now dig into why and how to use Scribe with Salesforce App Cloud.
OAuth2 with Scribe
OAuth2 is a standard that allows different customizations, i. e. by defining access scopes or using one of the available extensions like JSON Web Tokens (JWT). That leads naturally to different OAuth2 provider implementations.
Scribe gives you an additional layer via several included API implementations, which frees you from the hassle of learning (most of) the different implementations. Besides the pure OAuth2 authentication process it also provides methods to use OAuth-ed http requests – a very nice addition IMHO.
Scribe and Salesforce App Cloud
OAuth20Service service = new ServiceBuilder() .apiKey(clientId) .apiSecret(clientSecret) .callback("https://www.example.com/callback") .build(SalesforceApi.instance());
The ServiceBuilder connects to the App Cloud environment with the given API key and secret. The shown callback site (must be HTTPS for App Cloud) is used as return point after the successful, initial authentication process.
SalesforceToken accessToken = (SalesforceToken) service.getAccessToken(codeEncoded);
The next step is now to create the access token, so that we can access restricted resources. In the above example “codeEncoded” represents the access token string, that has been passed to the callback site.
That’s all with the whole OAuth2 dance. The next step would be now to read some data.
String queryEncoded = URLEncoder.encode("Select Id, Name from Account LIMIT 10", "UTF-8"); String url = accessToken.getInstanceUrl() + "/services/data/v37.0/query?q=" + queryEncoded;
We keep it simple here and are executing a SOQL query to read the Id and Name fields from 10 Account objects. The call accessToken.getInstanceUrl() is special to the Salesforce OAuth2 implementation. The value for this comes from a custom response value in the JSON Web Token.
OAuthRequest request = new OAuthRequest(Verb.GET, url, service); request.addHeader("Authorization", "Bearer " + accessToken.getAccessToken()); Response response = request.send();
The response object offers two methods, response.getCode() for returning the HTTP response code and response.getBody() for returning the actual data.
Done! Easy, right?