28

I'm dealing with quite an unusual issue here, and was wondering if anyone had figured this out.

I'm trying to implement an OAuth flow from one salesforce instance to another (any other). And one of the issues I've run into is if the other instance has the same instance url of the "origin" instance. Everyone's encountered this, when you login to the other instance, you'll be logged out of the original one.

So, to try to get around this, I'm trying to use the frontdoor.jsp (http://docs.releasenotes.salesforce.com/en-us/winter14/release-notes/security_frontdoorjsp.htm) method.

So I'm passing in the UserInfo.getSessionId() in the "state" param, and my pass-through application (hosted on heroku) is forwarding the request back through frontdoor.jsp using the session id passed through.

Now, I was getting a really hard time getting this to work, but what I ended up noticing is that for each context, I was getting different output from the "UserInfo.getSessionId()" call. Not all of them worked when passing through frontdoor.jsp. Here's a summary of the different places I tried it:

  1. Printing Session Id out to a visualforce page:
    • Didn't work when passing this value through frontdoor.jsp
  2. Print session id in debug log from VF controller
    • Same session id as #1, still didn't work for frontdoor.jsp.
  3. Print session id in developer console:
    • Different session id from the VF page, but this one worked on frontdoor.jsp.
  4. Print session id from a trigger:
    • Yet another different session id, but worked with frontdoor.jsp
  5. Printed from "Execute Anonymous" in Eclipse
    • Yet another session Id, but also worked with frontdoor.jsp.

So what I need to know is this: how do I get the "proper" session id that works with frontdoor.jsp when I'm in the context of the Visualforce controller?

13

I think the only way you can use your Session ID for frontdoor.jsp is if it was generated in the context of a first class Salesforce session: ie $Api.Session_ID on a Custom Link or Custom Button appearing on a native page layout on the *.salesforce.com domain or *.my.salesforce.com (per 'My Domain' feature), or Developer Console (tooling API), Eclipse execute anonymous (SOAP API).

As you've discovered, the Salesforce session system is both highly complex but well architected (in terms of both security and user experience). There are several different variations I've encountered:

  1. Session ID from na1.salesforce.com,

  2. Session ID from OAuth eg username-password flow (not sure about this, see commentary)

  3. Session ID from c.na1.visual.force.com,

  4. Session ID from namespace.na1.visual.force.com,

  5. Session ID from $Api.Session_ID

  6. Session ID from Site Guest User or other anonymous context

1) and 2) are first class citizens and can be used to log in via frontdoor.jsp, but 3) and 4) will not allow you to use the API, nor access pages on other namespaces or setup pages, nor log in. 5) gives you API access but no login. 6) Will work with the Identity URL but that's about it.

A Visualforce session cannot be promoted to a Salesforce session. They can only be converted to Visualforce sessions in other namespaces by redirecting a series of HTTP requests through /visualforce/session :(

If you really need to get your user into another org as a first-class citizen, the best-supported mechanism might be deploying a Salesforce Authentication Provider into the target org, then directing the consuming users to those single sign on URLs.

  • Can you explain what the reasoning is as to why the VF session id is not "first class?" It seems to me that this would be the most frequently used one in terms of "UserInfo.getSessionId()" – Evan Dec 31 '13 at 18:43
  • Furthermore, that article I linked would be far more useful if one could use the session id from a visualforce context. I'm not sure when you'd use the "UserInfo.getSessionId()" method otherwise. I guess you could use it via an API call, but presumably you already have an access token at that point. So either that document needs to be changed, or clarified. – Evan Dec 31 '13 at 18:47
  • Salesforce interfaces are robust, mostly declarative, and less likely victims of XSS, XSRF, injection attacks or client-side callouts. In Visualforce I figure the developer has a lot more weight to swing around. It's easy to hang yourself and easy to be naughty. So the bar is raised to usually encourage user consent (eg following a browser-facing OAuth flow) before doing anything drastic with a cocked and loaded Session ID. – bigassforce Dec 31 '13 at 19:18
  • I suppose I can understand that, it just smacks of irony to me that I'm encountering this issue while trying to develop a browser-facing OAuth flow. In the context of Visualforce there isn't much that the developer can't get access to, so it seems somewhat arbitrary that the line is drawn on allowing VF to see the session ids. So we've got a situation where my code can do almost anything the native interface can, but can't implement a proper, seamless OAuth flow to another Salesforce organization. I don't mean to be angry or insult anyone, it's just that this setup doesn't make much sense. – Evan Dec 31 '13 at 19:43
  • 1
    I tried with both "full" and "web" – aaronbauman Apr 24 '14 at 13:28
-2

I was also running into SessionID related issues in a completely different use case. You can find all the details here: Get a FIRST-CLASS SessionID for API Calls (looking for a clean way or alternative)

Telling the long story short, if you can store your users login-credentials in a custom object using encrypted fields, you can simply create a first-class SessionId via the login() method of the partner API. It's very easy to call via the AJAX Toolkit:

sforce.connection.login(username,passwordAndToken);

Looking at the callout XML produced by sforce.connection.login() in firebug, you can use it from inside APEX via a HttpRequest(). This Id should also be usable in this scenario.

  • 1
    I worked on an application that stored SFDC credentials as encrypted tokens and would avoid doing it again if at all possible. One of the high points of using OAuth is that you can get a refresh_token, with a configurable scope, that can be used again and again to get session ids. The massive benefit from a security standpoint is that you are not storing passwords in a format that can be decrypted! – dana Aug 20 '15 at 16:00

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.