Most apps that access the Force.com APIs do so on behalf of ‘full’ Salesforce users, gaining access to all of the Contacts, Accounts and other standard and custom objects that the user has access to, but it’s also possible for apps to call the APIs on behalf of Portal users, manipulating the Contacts, Cases etc that the Portal user can access. Until now, the only way for apps to authenticate Portal users has been to use the login() SOAP API call, setting orgId and portalId in the SOAP LoginScopeHeader. With the Spring ’13 release, apps can now use OAuth 2.0 (see also Digging Deeper into OAuth 2.0 on Force.com) to obtain tokens for accessing APIs on Portal users’ behalf. Not only do apps no longer need to handle user credentials, Portal users can now authenticate to the Portal via Auth Providers or SAML as well as username/password. Let’s take a closer look…

The first step in enabling OAuth for your Portal users is to associate a Force.com Site with your Portal, if you have not already done so. The Site provides your Portal with a unique URL and allows you to create a custom login page. Apps that wish to login users for the Portal must use the hostname from the Site’s secure URL when redirecting users to the OAuth 2.0 authorization service. For example, rather than redirecting to

https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>

instead use

https://mysite.secure.force.com/services/oauth2/authorize?response_type=code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>

The authorization service will recognize the custom hostname and further redirect the user to the Site login page, assuming the user is not yet authenticated. Note – if your site uses a path as well as the site domain, for example, https://mysite.secure.force.com/mypath, you will need to include that path in the authorization URL:

https://mysite.secure.force.com/mypath/services/oauth2/authorize?response_type=code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>

Here’s a simple Portal login page that allows users to login with username/password or via a Facebook Auth Provider (source code):

Looking at the login page controller, notice that we capture the value of the incoming startURL parameter. Passing that value to the Site.login() Apex call, or as a query parameter to the Facebook Auth Provider, ensures that, once the user is authenticated, they will be redirected back to the app.

The final piece of the puzzle is that the user must have the ‘API Enabled’ permission on their profile. Since you can’t set this on the default ‘High Volume Customer Portal’ profile, you will need to create a custom profile as a clone of the existing one and check ‘API Enabled’ on that custom profile.

This is all getting a bit abstract; let’s make it real by taking a look at the process in action. Before recording the video, I revoked permissions for my app on my Portal user’s record in Salesforce, and for the Portal on my Facebook account, and logged out from everywhere, so you can see the entire process. Second time round I just logout from my app and the portal. Since I’m still logged in to Facebook, one click at the Portal login page is all it takes to login to the app.

//www.youtube.com/watch?v=qpn-skZmb8U

Now it’s easier than ever to write apps for Portal users, I hope this article has sparked an idea for a new app. Let me know in the comments what you’re thinking…

Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • Chirag Mehta

    Been waiting for this since long, great post Pat. This will guide in developing easy to use(login) apps for portal users too.

  • Alessio Valentini

    Hi.

    This is working perfectly. I have a problem though. When authenticating the page it’s not recognizing the page as an https website.

    “You attempted to reach thepinkhouse.phase2full.cs13.force.com, but instead you actually reached a server identifying itself as *.cs13.force.com. This may be caused by a misconfiguration on the server or by something more serious. An attacker on your network could be trying to get you to visit a fake (and potentially harmful) version of thepinkhouse.phase2full.cs13.force.com.
    You should not proceed, especially if you have never seen this warning before for this site.”

    The problem is that using a normal browser you can click “procede anyway” and it simply put a red cross on the https. When using a mobile app this is breaking the login process because it’s not possible to click “procede anyway” and the user remains stuck in front of a white screen.

    This should be simply recognized as a valide https and work right away.

    Any idea?

  • http://twitter.com/hemmeter Scott Hemmeter

    This same concept applies to SSO where you use the My Domain rather than Sites. Brilliant!

  • Thomas Gagne

    Did you skip a step? How did the portal user register, and how does the Facebook login match with a portal user? Does it look at the Facebook email and find the portal user using their email? What happens if two portal users have the same email address?

  • Sidharth Agarwal

    Hey , can we create a mobile app (ios / android) for PORTAL USERS? May be using Salesforce Mobile SDKs.
    I have been having difficulty on how to do it for PORTAL USERS, any link, guidance will be appreciated.

    • http://blog.superpat.com/ Pat Patterson

      Yes – for portal users you open the app’s Settings page (in the iOS Settings app) and set the custom host to the secure site URL’s hostname – e.g. mysite.secure.force.com – and set Login Host to ‘Custom Host’.

      • http://blog.superpat.com/ Pat Patterson

        Note that if you are doing SSO with another system – e.g. using a Facebook Auth Provider, you will need to whitelist all of the appropriate hosts by adding them to External Hosts in Supporting Files/Cordova.plist . For Facebook, you would add *.facebook.com, *.fbcdn.net, and fbstatic-a.akamaihd.net

      • Sidharth Agarwal

        Hey Pat, can you please share the remote access -> callback url format with us. Also do we need auth providers for this scenario, and if yes we probably need to copy the auth provider callback url to remote access callback url ? If no, then the remote setting -> callback url will be sfdc://success ? Please help.

  • Anonymous

    Hi Pat,

    I’m trying to get OAuth working with my site and the Salesforce Customer Portal users, but there seems to be one problem that I keep hitting. When a user is taken to the customer portal login screen, and they login, they are NOT asked to authorize the app and are NOT taken back to my site. They are simply logged into Salesforce and brought to the portal homepage.

    If an authenticated customer portal user uses the OAuth process, they are taken to the authorization page if they haven’t authorized the site before. or they taken right back to my site if they have authorized before.

    One last “variable” is that I’m using “https://mysite.secure.force.com/sitename” instead of just “https://mysite.secure.force.com”. If I try the one without the site name appended, I get an error page saying that the the site is under construction…

    So this almost works, but not if the user needs to login:

    https://binarytree.secure.force.com/mysitename/services/oauth2/authorize

    And this gives me “under construction”:

    https://binarytree.secure.force.com/services/oauth2/authorize

    (In both scenarios I am passing in the response_type (code), client_id, and redirect_uri.

    Any idea what I’m doing wrong? Sorry if this is a simple one, I’m a Salesforce noob.

    Thanks,
    John Bubriski

  • Srikanth Gannavarapu

    Hi Pat,

    Thank you so much for the article, it worked perfectly, I have
    an issue with portal custom login page for ipad app. The page I have
    configured on active home page in site is not reflecting, instead it is
    going to force.com login page. Can you please guide me where to configure this?

  • Srikanth Gannavarapu

    Hi,

    We have created site with custom login page for portal users and it is working fine in web with our custom UI.

    In our App when we map this site SFDCOAuthLoginHost for OAuth Authentication using Salesforce SDK. It brings me the default force.com
    site page. The oAuth authentication process is working fine but it
    brings the default site login page. Why the Salesforce SDK brings the
    default login page ?

    There is no issue in setting of SFDCOAuthLoginHost, we are fine on that front. we don’t want to reset the value too.

    The exact problem is on login page, the App should bring the custom login page of the site but it shows the force.com site login page.

    We could modify the look and feel of default login page but it will affect others sites. Please advice me.

  • Jeremy Henson

    For the portal user scenario where the portal is actually SAML SP, would you just customize the SiteLogin/unauthorized sites page to redirect to the SAML IdP, sending the OAUTH token URL as a relay state? Seems like after they are authenticated at the IdP, they would get relayed back to the custom SFDC sites OAUTH endpoint – that the right way to do that?

    • http://blog.superpat.com/ Pat Patterson

      I believe so, but I’ll check…

  • Clara

    What is I want to try this in my sandbox first? how do I configure the URL so it access the sandbox instead a DE or Production enviroment ?

    • http://blog.superpat.com/ Pat Patterson

      Change login.salesforce.com to test.salesforce.com and it should work for a sandbox.

      • Clara

        if I change it to test.salesforce.com it work good for “normal users” but not to authenticate portal users

        • http://blog.superpat.com/ Pat Patterson

          Ah yes – apologies – you will need to use the Sandbox portal hostname – something like https://portalname.sandboxname.cs13.force.com/. Note, though, due to the way that SSL works in sandbox portals, you will see certificate errors – see the other comments on this post for more details.

  • Phil

    Is it possible to do the entire authentication process (standard not FB) programatically if you have the portal users credentials? For example in a scheduled class? I’d like to be able to authenticate as a portal user to reach a REST endpoint.

  • technudger

    So, this obviously works for the User-Agent or Web Server oAuth flow in Salesforce, but does it work with the Username-Password flow? I have my Portal linked to the Site and have the custom login page set as the home page for the Site. However, in this flow, how are the user credentials passed to and authenticated against the Portal?

    • http://blog.superpat.com/ Pat Patterson

      No, it doesn’t work for username/password flows. Use SOAP login with LoginScopeHeader: http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_header_loginscopeheader.htm

      • Keith Clarke

        Can you clarify whether the password flow can ever be used for customer portal users? See http://salesforce.stackexchange.com/questions/19121/should-oauth2-with-grant-type-password-work-for-high-volume-customer-portal for detail of the problem I am having with this combination.

        • http://blog.superpat.com/ Pat Patterson

          No – you can’t do OAuth username/password with customer portal users. I just left a comment on the question at Salesforce StackExchange asking why you’re trying to use this particular combination…

          • Keith Clarke

            Thanks for taking the time to reply on this fairly old blog post – it is appreciated. I’ve commented on Salesforce StackExchange in a bit more detail – please take a look. What is the reason to disallow this mechanism for that license?

          • http://blog.superpat.com/ Pat Patterson

            OK – answered over on StackExchange.

          • Thomas Gagne

            What’s the link on stack exchange? I need to see the question. We have a situation where Salesforce is providing a utility to another website, and each of the users of the other website need to authenticate to Salesforce as community users–but never know they’re using Salesforce. They can’t give permission for Salesforce to use their credentials because they don’t know Salesforce is behind the scenes, and there’s middleware between the client-facing web app and Salesforce.

            It’s really Salesforce providing a utility that includes enforcing sharing rules.

          • http://blog.superpat.com/ Pat Patterson

            Hi Thomas – the referenced answer is at http://salesforce.stackexchange.com/a/19328/67

            You can customize the Salesforce login for community users, and set the connected app policy so that admin-approved users are pre-authorized – they will never see the Salesforce logo on login, and never see an authorization screen.

  • Mark Sivill

    Hi Pat,

    I’m converting an existing oauth app to now use salesforce communities ( with external users being partner portal users )

    I seem to get a forbidden (status 403) when trying to using “/connect/batch”. Is there anything special that needs to be done to use /connect/batch with partner portal users?

    Thanks

    Mark

    • http://blog.superpat.com/ Pat Patterson

      /connect/batch should be available to portal users, yes. There’s nothing special about that endpoint and, in fact, it doesn’t check any perms on access (only on each individual call within the batch). Sounds like you’re not getting into the front door, though?

      • Mark Sivill

        So it gets past the front door, as it calls the identity service before the /connect/batch and that works fine

        Interestingly the user type from identity service coming through as POWER_CUSTOMER_SUCCESS so not sure if this has any relevance to this……

        • http://blog.superpat.com/ Pat Patterson

          Have you double checked the URL you’re using? It should be something like https://instance_name/services/data/v29.0/connect/batch – i.e. no /chatter component. Grasping at straws a little here, though, since a mistake there would likely generate a 404. Have you verified that the user, with the same token, can do the individual operations?

          • Mark Sivill

            Hi Pat,

            I will try to breakdown the /connect/batch into individual calls, I would have hoped any errors with the sub URLs would not bubble up to the surrounding /connect/batch

            I will also see if I can replicate it somehow in workbench, not sure how to set the user to be a portal one at the moment.

            Thanks

            Mark

          • http://blog.superpat.com/ Pat Patterson

            Hi Mark,

            I’ve been in touch with R&D – this information would really help in narrowing the issue down.

            1) Can this user access other REST API endpoints or is the problem isolated to /connect/batch?

            2) Can other portal users in the org access /connect/batch?

            If other portal users in the org can, it is just portal users tied to this profile (or permission set) that can’t?

            If you can’t get Workbench working, I find curl is useful for this sort of testing. If you can get a session id (browser cookie is often favorite) you can do something like:

            curl -v -H ‘Authorization: Bearer SESSION_ID’ -d ‘{ “batchRequests” : […] }’ https://c.prerelna1.visual.pre.force.com/services/data/v29.0/connect/batch

          • Mark Sivill

            Hi Pat,

            So I did need to change one of the sub urls anyway but issue seems to still exist. I’ve attached a cut down senerio to show issue, please let me know if we need to transfer this conversation elsewhere rather than clutter up this blog.

            So the following works (notice use of connect but using organization instead of batch)

            curl –header ‘Authorization: OAuth ‘ https://.salesforce.com/services/data/v28.0/connect/organization

            This also works (with community id in endpoint)
            curl –header ‘Authorization: OAuth ‘ https://.salesforce.com/services/data/v28.0/connect/communities//chatter/users/me

            The following connect/batch errors

            curl –header ‘Authorization: OAuth ‘ -d ‘{“batchRequests”:[{“method”:”Get”,”url”:”/services/data/v28.0/connect/communities//chatter/users/me”},{“method”:”Get”,”url”:”/services/data/v28.0/connect/organization”}]}’ https://na15.salesforce.com/services/data/v28.0/connect/batch

            with

            [{“message”:”The requested API is not available to portal users. You may need to specify a community for portal user access.”,”errorCode”:”FUNCTIONALITY_NOT_ENABLED”}]

            This is the only portal user I have in the org, which I created just to test this so have no other portal users to compare this with. It feels like I’m missing a simple step here but can’t see it at the moment.

            Any pointers you have would be great.

            Thanks

            Mark

          • http://blog.superpat.com/ Pat Patterson

            Yep, it’s a bug – the fix should be available in Winter ’14 in a couple of weeks. Thanks for finding, reporting and working this, Mark!

          • Mark Sivill

            Hi Pat,

            Thanks for following up with R&D, in the Winter 14 drop will the fix work with the existing endpoint version 28.0 or will it need to be updated to 29.0?

            Thanks

            Mark

          • http://blog.superpat.com/ Pat Patterson

            The fix should affect all versions of the API, so 28 and 29 will both work.

          • Mark Sivill

            Hi Pat,

            All upgraded to 29 and we now have a chatter like button that can work with salesforce communities. Unfortunately success.salesforce.com api are not enabled for users or I could I have show you a live demo.

            Thanks again for your help.

            Mark

          • http://blog.superpat.com/ Pat Patterson

            Good to hear – thanks for closing the loop!

        • http://blog.superpat.com/ Pat Patterson

          Note that the sub URLs must be scoped to a community in the sub request – might want to check that…

  • Sebastian Claros

    Hi Pat,

    I have a security issue with the guest profile. When I open /services/oauth2/authorize then shows me a “Authorization Required” and in the detail error appear “Page not allowed for profile:/setup/secur/RemoteAccessAuthorizationPage.apexp”.

    On the other hand if I’m logged automatically show’s me the grant page.

    I changed settings all around salesforce with no luck. Any thought what I could be missing.

    Thanks on advance,

    Sebastian

    • http://blog.superpat.com/ Pat Patterson

      I’m not sure I understand the issue here. The guest user isn’t allowed to authorize access, but logged in users can. What’s the problem?

      • Sebastian Claros

        Sorry Pat, the issue was that the Authorization Page was showing an error message only and didn’t have the login form, so we thought that was something wrong in the public profile. Sounds stupid but we loose some hours until we found it! Thanks for post and your support !

  • Danat Pomeranets

    Hi Pat,

    thank you for yet another great article. Just a question to the example source code – would you be able to post the CSS file used in it? It would be a great starting point to extend the example provided by you.

    Thanks and kind regards,
    Danat

  • Rastko Isajev

    Should be also changed domain name for second part of the OAuth 2.0 handshake where you are requesting access&refresh tokens or it should remain as it was ?

    https://login.salesforce.com/services/oauth2/token
    or
    https://mysite.secure.force.com/services/oauth2/token

    Thanks,
    Rastko

  • Aaron Bauman

    Where do I get the endpoint for a force.com portal site in a sandbox?

  • Rishabh Shah

    Hello,
    I am looking for the answer posted in the given below url.

    http://salesforce.stackexchange.com/questions/45223/salesforce-oauth-endpoints

  • John Thompson

    I’m struggling with this a little bit. I can get OAuth working just fine for regular SF users, both in Production and Sandbox. But I can’t seem to get it to work for Portal users. I’ve got a Site setup and connected to the Portal, and the user has access to that portal. I’m not sure that I’ve got the endpoints setup correctly. I have custom domains enabled in my Production and Sandbox orgs (with re-directs enabled).

    The application launches and re-directs the user to the login page, but the URL somehow migrates back to:

    https://test.salesforce.com/?ec=302&startURL=/setup/secur/RemoteAccessAuthorizationPage.apexp?source=….

    After entering User Name and Password, I get the “login attempt failed” message. Does anyone have any suggestions?

  • Sidharth Agarwal

    My company is looking to build a customer portal outside of SF, and so we are looking a way to REST authenticate the portal users to fetch the access token/session id, which can be used to call other apex custom REST services to get SF data related to that portal user. Is this blog approach can be used for this? Thanks.

    • http://blog.superpat.com/ Pat Patterson

      Yes – exactly.

      • Sidharth Agarwal

        Thanks Pat for reply. Is there any way, we don’t have to use the SF Site and escape portal user to see the sf authorization page ?
        Our goal, is to build a login page, where the portal user can put there login information, and that will take them inside portal (build outside of SF). The REST authentication to get the access token happens in the background.

        • http://blog.superpat.com/ Pat Patterson

          I don’t understand what you’re asking. You want to collect the user’s username and password in your own login page? Or do you want to use the Salesforce login page from your external portal site?

          • Sidharth Agarwal

            I want to use login page from our external portal site. So basically everything (portal) is outside of SF, and whenever the portal user enters username and pw on this site, it should make a REST authentication call to SF, to get the session id back. Also its desired to have the authorization happens in the background, ie. not have users to click Allow or Deny.

          • http://blog.superpat.com/ Pat Patterson

            Can’t do it through REST (OAuth is the preferred method there), but you can use the SOAP login() call (see https://www.salesforce.com/developer/docs/api/Content/sforce_api_calls_login.htm) – you’ll need to set the profile id and org id in the LoginScopeHeader.

          • Sidharth Agarwal

            Thanks for the confirmation, that’s what i guessed.
            So we can use SOAP for portal user authentication, get the session id back, and use session id to make calls to custom apex REST services to get user related data.

          • http://blog.superpat.com/ Pat Patterson

            Yes. You’ll need to figure out the instance url from the SOAP login response, but it’s pretty straightforward.

  • Amit Chakraborty

    I want to authenticate portal users with OAuth for my app outside Salesforce.

    I am calling the authorize service through the REST API as mentioned in the blog above

    https://mysite.secure.force.com/services/oauth2/authorize?response_type=code&client_id=&redirect_uri=

    but instead to getting redirected to the custom site login page I am getting redirected to the “Unauthorized access” page.
    Is there a setting that I am missing ?

  • Arun sakthi

    hi

    I have used the above link to logon the my site. but it provide error that is’Authorization Required You must first log in or register before accessing this page. If you have forgotten your password, click Forgot Password to reset it.’

    how to resolve it?

    another one my site not https. only http , i try

    http://mysite.secure.force.com/mypath/services/oauth2/authorize?response_type=code&client_id=&redirect_uri= but it also provide https required error.

    please any solution for above scenario. thanks in advance!

    • http://blog.superpat.com/ Pat Patterson

      You will need to use HTTPS.