4

We have chosen to use "Username-Password OAuth Authentication Flow" over the "Web Server OAuth Authentication Flow" and "User-Agent OAuth Authentication Flow" because we need to login silently, without user interaction.

We will be authenticating users from Android/iOS apps using REST web services.

  • Is the "Username-Password OAuth Authentication Flow" the least secure flow?
  • What possible security issues should be taken into account when using this flow?
  • grant_type, client_id, client_secret, username, password will be sent as URL parameters. Is it possible to POST these parameters as JSON?
3

Answering your questions in order:

  • In the interactive web server/user-agent flows, the user submits their credentials directly to Salesforce, and the app receives the short-lived access token and, optionally, a long-lived refresh token. The refresh token is scoped to that application, and may be revoked by the user or an admin at any time, without any impact on other applications. The admin can even set policy for refresh tokens, choosing to invalidate them after some period of inactivity etc. This is not true of username/password - the user shares their Salesforce credentials with the application. If, at a later time, the user decides that they do not trust that app, they needs to change their password at Salesforce, and update any other apps that might be holding the username and password.
  • The app is responsible for safely handling and, possibly, storing those credentials, which have much wider scope than the refresh token. It's not that the username/password flow is less secure than the interactive flows, it's that the responsibilities of the app are much greater, and the consequences, if the app does not fulfill those responsibilities, more severe.
  • They are not sent as URL parameters, but posted as application/x-www-form-urlencoded data - see this article.

I would advise you to consider one of the interactive flows, and store the refresh token, or even JWT Bearer Token flow, where the app creates a signed token, rather than username-password, which should be considered a last resort, when no other option is available.

2

Is the "Username-Password OAuth Authentication Flow" the least secure flow?

Yes. The documentation for this flow suggests that you should only ever use this for development in lieu of using an appropriate flow (Web-Server, User-Client, etc). You can use it to wire up an access token while you're working on the main app, before you've implemented the main login flow.

What possible security issues should be taken into account when using this flow?

You have to store the user's username and password on the device, or require the user to enter this information every couple of hours (session timeout value). You will not be issued a refresh token. This means that, unless you do the value store correctly, you're risking exposing authentication data unnecessarily.

At least with a refresh token, all you have to do is revoke the session to lock out a stolen session, while with the username-password flow, you'd have to require the user to reset their password and change it for all programs that use the password (e.g. Data Loader, other older systems that don't support OAuth, and other programs that use username-password flows).

Technically, your app won't even pass a security review if you use this flow, and salesforce will probably revoke your client_id to prevent compromises if you use this flow in an app.

Finally, the client_secret is a secret, a password that should considered secret. Client apps are inherently insecure and should not contain the client_secret. Exposing this value means if it's leaked, you'll have to change your client_secret in the master configuration, and update this value for all affected apps and servers.

In the event of a client_secret compromise, malicious programs can masquerade as your program, appearing legitimate while actually having nefarious purposes. This is why you don't want your client_secret floating about.

grant_type, client_id, client_secret, username, password will be sent as URL parameters. Is it possible to POST these parameters as JSON?

Yes, you can choose to use GET or POST. The documentation actually suggests using POST, as it uses the term "request body", which starts after a pair of newlines. It will be the same query string (name-value pairs with escaped URL characters for reserved/recommended escape characters) as you would produce in a GET request, except that it appears in the body instead of the header.

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.