I'm implementing an API and a client-side web app, and they are supposed to communicate via an API and use OAuth 2 for authentication.
I can't get over my confusion on what's the right way to authenticate users (i.e. without major security oversights).
I gathered the following:
- Ideally, you should expose a web form on the API server which takes username and password and redirects back with an authorisation code, to be exchanged client-side for an access token access token.
- The approach I described is considered cumbersome, so OAuth 2 offers an implicit flow where the client-side app makes a request containing a
client_id
and the user's credentials, which it gathers. It receives an access token. - Authentication toolkits seem to be wary of allowing only the
client_id
to be passed, and instead require theclient_secret
to be included. - Based on the previous point, as a developer you may have to embed your
client_secret
in the distributable application, thus making it public. - Some peers with an understanding of OAuth 2 told me that it is not uncommon for developers to embed the
client_secret
in their distributables, and that some high-profile services (allegedly Twitter) do it as well. - If you add a proxy between the client and the OAuth 2 server to add the
client_secret
to requests, it doesn't improve security as it is similar to ignoring theclient_secret
altogether. - The only security concern that I could find related to embedding
client_id
andclient_secret
in the client is that an attacker may implement their own client which, when given user credentials, may act on behalf of the user. This does not seem a likely attack, as phishing is similar and yields bigger benefits.
The following questions are still unanswered for me:
- What is the difference between the Client Credentials flow and the Resource Owner Password flow? Which one should I prefer? The answers to this question do not give me a clear understanding of the difference.
- Are there any major security concerns with using the implicit flow, or is it viable?
- Is embedding the
client_secret
safe?
- If not, what is the alternative? Should I still require a
client_id
, or allow using "public" (unregistered) clients?