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_idand the user's credentials, which it gathers. It receives an access token.
- Authentication toolkits seem to be wary of allowing only the
client_idto be passed, and instead require the
client_secretto be included.
- Based on the previous point, as a developer you may have to embed your
client_secretin 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_secretin 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_secretto requests, it doesn't improve security as it is similar to ignoring the
- The only security concern that I could find related to embedding
client_secretin 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
- If not, what is the alternative? Should I still require a
client_id, or allow using "public" (unregistered) clients?