OAuth 2 for native app - what's the difference between public and private client types?

I was trying to implement OAuth 2 provider for a web service and then I built my own app on top of it. I also want to provide API access to third party developers.

I have already read the OAuth 2 spec and cannot choose the correct flow. I want to authenticate CLI and GUI applications as well.

First of all, we have two types of clients - public and private. Of course, GUI and CLI applications will be publicly available. But what is the difference between these two types? In that case, what do I need the client_secret for if I can get the access token without it by just changing the client type?

I tried to look at some API implementations of popular services like GitHub. But they use HTTP Basic Auth. Not sure if this is a good idea.

Is there any particular difference? Does one level of security increase over another?

+12


source to share


2 answers


For the difference between public and private clients, see http://tutorials.jenkov.com/oauth2/client-types.html which says:

Confidential Client is an application capable of maintaining a client password that is confidential to the entire world. This client password is assigned to the client application by the authorization server. This password is used to identify the client to the authorization server to avoid fraud. An example of a confidential client would be a web application where no one other than the administrator can access the server and view the client password.

An open client is an application that is incapable of keeping the client password confidential. For example, a mobile phone app or desktop app with a client password embedded inside It. Such an application can be hacked, and it can be a password. The same is true for a JavaScript application running in the user's browser. The user can use the JavaScript debugger to search the application and see the client's password.



Confidential clients are more secure than regular clients, but you may not always be able to use confidential clients due to the limitations of the environment they run in (native cq applications, browser clients).

+14


source


@HansZ's answer is a good starting point as it clarifies the difference between a public and private client application: the ability to keep the client secret secret.

But that doesn't answer the question: Which OAuth2 profile should I use for which use cases? To answer this critical question, we need to delve deeper into the problem.

For sensitive applications, the client secret is provided out-of-band (OOB), usually by configuration (for example, in a properties file). For browser and mobile apps, there really is no way to do any customization, and therefore they are considered public apps.

So far, so good. But i disagree that this makes such apps unable accept or store refresh tokens. In fact, the redirect URI used by SPAs and mobile apps is typically localhost

and, thus, 100% equivalent to receiving the tokens directly from the token server in response to a Resource Owner Password Credentials Grant (ROPC).

So far, so good. But I disagree that such applications cannot accept or save refresh tokens. In fact, the redirect URI used by SPA and mobile apps is usually localhost

and thus 100% equivalent to receiving tokens directly from the token server in response to an RODC (ROPC). Many authors point out, sometimes correctly, that OAuth2 does not actually perform authentication. In fact, as stated in OAuth2 RFC 6749, both ROPC and Client Credentials (CC) are required to perform authentication. See Section 4.3 and Section 4.4 .

However, this statement is true for grants Authorization Code

and Implicit

. But how does authentication actually work for these domains?

Typically, a user enters their username and password into a browser form that is published on an authentication server that sets a cookie for their domain. Sorry, but even in 2019, cookies are the state of the art in authentication. Why? Because cookies are how browser applications maintain state. There is nothing wrong with them, and browser cookies are reasonably secure (domain is protected, JS applications cannot receive "http only" cookies, TLS / SSL is required for security). Cookies allow you to display login forms only on the first authorization request. After that, the current identifier is reused (until the session expires).

Ok, then what is the difference between the above and ROPC? Little. The difference is where the login form came from. In SPA, the application is known from a TLS / SSL authenticated server. So this is almost identical to how the form is rendered directly by the server. Either way, you trust the site over TLS / SSL. For a mobile application, the form is known to be received from the application developer through the application signature (applications from Google Play, Apple Store, etc. are signed). So again, there is a trust mechanism similar to TLS / SSL (no better, no worse, depends on storage, CA, trusted root distributions, etc.).

In both scenarios, a token is returned to prevent the application from re-sending the password on every request (which is why HTTP Basic authentication is bad).



In both cases, the Authentication Server MUST be protected against attacks from any Internet Logon Server. Authorization servers don't have this problem because they delegate authentication. However, OAuth2 password

and client_credentials

de facto profiles serve as authentication servers and therefore should really be tough.

Why would you prefer ROPC over an HTML form? Non-interactive cases, such as a CLI, are a common use case. Most CLIs can be considered confidential and, thus, should have both a client_id

and client_secret

. Note, if running on a shared OS instance, you should write your CLI to pull the client secret and password from a file or, at least, the standard input to avoid secrets and passwords from showing up in process listings!

Why do you prefer ROPC over HTML form? Non-interactive use cases like the CLI are common use cases. Most CLI can be considered confidential and therefore must have both client_id

, andclient_secret

... Note, if you are running an instance of a shared OS, you must write your CLI to extract the client's secret key and password from a file, or at least standard input to avoid secrets and passwords appearing in process lists! Native apps and spas are another good use, imo, because these apps require tokens to be passed to REST services. However, if these applications also require cookies for authentication, you probably want to use authorization code or implicit streams and delegate authentication to a regular web login server.

Likewise, if users are not authenticated in the same domain as the resource server, then you really need to use authorization code or implicit grant types. The user must log in to the authorization server.

Things get more complicated if two-factor authentication is used. I haven't crossed that particular bridge yet. But I've seen cases, such as Attlassian, in which an API key can be used to allow access to accounts that typically require a second factor besides a password.

Please note that even when you host an HTML login page on the server, you must take care that it is not wrapped either by an IFRAME in the browser or by any Webview component in its own application (which can set hooks to view the username and the password you enter, how password managers work, by the way). But this is another topic related to "hardening the login server", but the answers to all questions are about clients adhering to web security conventions and thus a certain level of trust in applications.

A few final thoughts:

  1. If the refresh token is safely delivered to the application via any type of stream, it can be safely stored in the browser / native local storage. Browsers and mobile devices protect this storage quite well. This is, of course, less secure than keeping update tokens in memory only. So maybe not for banking apps ... But many apps have very long sessions (weeks), and here's how.

  2. Don't use client secrets for public applications. It will only give you a false sense of security. Client secrets are only suitable when a secure OOB mechanism exists to deliver the secret and it is securely stored (for example, OS permissions are locked).

+1


source







All Articles