8

Background

I am creating a Google Chrome Packaged App that allows users to access various features from a plurality of salesforce.com organizations. This app will allow users to perform various tasks depending on their permissions in each organization, such as querying data and logging in with a single click. To avoid storing passwords, I'm trying to use OAuth2 to generate refresh tokens that can be used to access those organizations, with a mechanism to revoke those tokens if needed across all organizations in the event of a compromise.

Problem

Generating a refresh token only happens in certain flows that follow a certain pattern, and those patterns seem to be incompatible with Google's "chrome.identity.launchWebAuthFlow" mechanism.

Attempted Solutions

So far, I have tried the following end-points to try and get Google Chrome to recognize that we've successfully completed the flow and obtain a refresh token. Here are my attempts so far:

/services/oauth2/authorize?
grant_type=code&
client_id=XYZ&
prompt=login&
scope=full+refresh_token&
redirect_uri=https://<appid>.chromiumapp.org/callback

This link follows the web server flow. We get a code back that we can use to call /services/oauth2/tokens, but ths requires the client_secret, which we are not supposed to embed in the code for security reasons-- the source code is open.

/services/oauth2/authorize?
grant_type=token&
client_id=XYZ&
prompt=login&
scope=full+refresh_token&
redirect_uri=https://<appid>.chromiumapp.org/callback

This link won't give us a refresh_token, because it does not have a custom protocol and does not match login.salesforce.com/services/oauth2/success.

/services/oauth2/authorize?
grant_type=token&
client_id=XYZ&
prompt=login&
scope=full+refresh_token&
redirect_uri=chrome-extension://<appid>/callback

This link results in an error in Google Chrome about not being able to load the authorization page, but would give us a refresh token if it worked.

/services/oauth2/authorize?
grant_type=token&
client_id=XYZ&
prompt=login&
scope=full+refresh_token&
redirect_uri=https://login.salesforce.com/services/oauth2/success

This page doesn't actually show an access token or error, so Google Chrome never detects that the flow is complete. We do not get an access token or refresh token. I have a feeling this is is the proper flow to use, but without a way to detect the token, it simply doesn't work. The authorization page simply sits open forever once we reach this step.

Question

How am I supposed to code this app such that it securely accesses salesforce.com without compromising the client_secret while preventing excessive login attempts and/or API calls from a periodic timer that would be required?

I realize that this question may be outside the scope of this forum, but this seems to be fairly salesforce.com specific, as other OAuth2 sites work just fine with chrome.identity.launchWebAuthFlow, so I thought I'd ask here and see if anyone knows enough about Chrome and OAuth2 as it pertains to accessing salesforce.com.

Cross-Posted

http://boards.developerforce.com/t5/APIs-and-Integration/How-do-I-get-an-OAuth2-refresh-token-in-Google-Chrome-Packaged/m-p/695323

4

When using OAuth2 with salesforce.com in a packaged app, you need to use a "webview" element and listen for the appropriate events. Here are the portions of the source that are relevant to the solution:

Page

<!DOCTYPE html>
<html>
...
    <body>
<!-- content required to have page eventually display interactive oauth2 -->
        <webview style="display: none; ... (set a nice width/height)" id="oauth2"></webview>
    </body>
</html>

JavaScript

(function() {
    var outh2frame;
    function showOAuth2Frame() {
        oauth2frame.style.display = 'block';
        oauth2frame.src = 'https://login.salesforce.com...';
    }
    function onWebViewLoadStart(event) {
        if(event.url.indexOf('/services/oauth2/success#')>-1) {
            // we've got success. Load the tokens and hide the frame.
        }
    }
    function onLoad(event) {
        oauth2frame = document.querySelector('#oauth2');
        oauth2frame.addEventListener('loadstart', onWebViewLoadStart);
    }
    addEventListener('load', onLoad, true);
}());

You also need to add the appropriate permission to your package in order to use a webview.

-1

Any chance you could share the solution? I am struggling with the same thing and I am getting an undefined response from the chrome identity call to my constructed URL.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.