5

This is all a proof-of-concept in a sandbox; maybe something I'm doing is not supported in sandboxes. Our org is set up with SAML2-based SSO and that works well. Now I'm trying to use a REST API and OAuth2 to authenticate, using web server flow. We have the "My Domain" feature enabled as per the articles on mixing SAML SSO with OAuth apps. I send a request like this (wget shown for simplicity):

wget -O - 'https://xxx.my.salesforce.com/services/oauth2/authorize?response_type=code&redirect_uri=XXX&client_id=YYY'

But instead of redirecting to our IdP login page, it generates a page with JavaScript that redirects to my redirect_uri appending a SAML app that I don't recognize from any setup we've done:

XXX/saml/authn-request.jsp?saml_request_id=ZZZ...

Naturally this is not found on my server. If I disable SSO for my account and try the same request, I get redirected to the standard salesforce login and I'm able to log in and authorize the application, and I get the auth code.

Is there something else in the setup that needs to be done?

Java Code to auth in to Salesforce.

StringBuffer data = new StringBuffer();
              data.append("response_type=code");
              data.append("&client_id=" + URLEncoder.encode("client_id", "UTF-8"));
              data.append("&redirect_uri=" + URLEncoder.encode("redirect_uri", "UTF-8"));

              URL url = new URL("mydomain.instance.my.salesforce.com/services/oauth2/authorize");
              HttpURLConnection connection = (HttpURLConnection)url.openConnection();
              connection.setDoOutput(true);
              connection.setRequestMethod("POST");
              connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
              OutputStreamWriter wr = 
                     new OutputStreamWriter(connection.getOutputStream());
              System.out.println(data.toString());
              wr.write(data.toString());
              wr.flush();
              InputStream in = connection.getInputStream();
              BufferedReader reader = new BufferedReader(new InputStreamReader(in));
              StringBuffer result = new StringBuffer();
              String line = reader.readLine();
              while(line != null) {
                     result.append(line);
                     result.append("\n");
                     line = reader.readLine();
              }
              wr.close();
              reader.close();
              System.out.println(result.toString());

Reponse : JavaScript that redirects to /saml/authn-request.jsp?saml_request_id=…

  • can someone throw some light on this please :/ – Rao Aug 28 '13 at 3:04
5

If you look at that response carefully, you'll see that the JavaScript actually makes a request of https://xxx.my.salesforce.com/, not your server. You need to follow one step further to see the request to your server. Here's an abbreviated version of what I just saw.

First, the initial OAuth request to a My Domain URL:

$ curl -v 'https://superpat-developer-edition.my.salesforce.com/services/oauth2/authorize?response_type=code&redirect_uri=...&client_id=...'
* ...
< HTTP/1.1 302 Found
< Location: https://superpat-developer-edition.my.salesforce.com/setup/secur/RemoteAccessAuthorizationPage.apexp?source=...

Following the redirect:

$ curl -v https://superpat-developer-edition.my.salesforce.com/setup/secur/RemoteAccessAuthorizationPage.apexp?source=...
* ...
< HTTP/1.1 200 OK
< ...
< 
<script>
var escapedHash = '';
var url = '/saml/authn-request.jsp?saml_request_id=...&saml_acs=...&saml_binding_type=HttpPost&Issuer=https%3A%2F%2Fsuperpat-developer-edition.my.salesforce.com&urlSource=1&RelayState=%2Fsetup%2Fsecur%2FRemoteAccessAuthorizationPage.apexp%3Fsource%3D...';
if (window.location.hash) {
   escapedHash = '%23' + window.location.hash.slice(1);
}
if (window.location.replace){ 
window.location.replace(url + escapedHash);
} else {;
window.location.href = url + escapedHash;
} 
</script>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
...
</html>

Note - no server on that /saml/authn-request.jsp URL, so the request will go to https://superpat-developer-edition.my.salesforce.com/. Let's simulate it with curl and see what happens:

$ curl -v 'https://superpat-developer-edition.my.salesforce.com/saml/authn-request.jsp?saml_request_id=...&saml_acs=...&saml_binding_type=HttpPost&Issuer=https%3A%2F%2Fsuperpat-developer-edition.my.salesforce.com&urlSource=1&RelayState=%2Fsetup%2Fsecur%2FRemoteAccessAuthorizationPage.apexp%3Fsource%3D...'
* ...
< HTTP/1.1 200 OK
< ...
< 

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">

    <body onload="document.forms[0].submit()">
        <noscript>
            <p>
                <strong>Note:</strong> Since your browser does not support JavaScript,
                you must press the Continue button once to proceed.
            </p>
        </noscript>

        <form action="https://ADFS.example.com/adfs/ls/" method="post">
            <div>
                <input type="hidden" name="RelayState" value="/setup/secur/RemoteAccessAuthorizationPage.apexp?source=..."/>                
                <input type="hidden" name="SAMLRequest" value="..."/>                

            </div>
            <noscript>
                <div>
                    <input type="submit" value="Continue"/>
                </div>
            </noscript>
        </form>

    </body>
</html>

And there's the request that's posted to the SAML endpoint you configured (in my case, https://ADFS.example.com/adfs/ls/). So - follow the chain one more link and you should see what's really happening.

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.