To minimise user friction, many apps cache the user’s username and password. However, storing passwords in a mobile device poses a security risk. To mitigate this risk, developers are looking at OIDC and OAuth 2.0 tokens. But do these make sense?
Read more about user and app authentication in our previous blog post.
OIDC and OAuth 2.0
OpenIDConnect (OIDC) and OAuth 2.0 are standards that are based on tokens. In its simplest form, a token can be viewed as a randomly generated string (i.e., password) that – when presented to the backend – will grant access to specific resources.
Contrary to popular belief, OIDC and OAuth 2.0 are not user authentication standards, neither specifies how users should authenticate. These standards only define how – after authentication – tokens are used to gain access to resources. Still, OIDC and OAuth 2.0 are heavily used in mobile apps for authentication purposes.
Replacing cached credentials by tokens
The classical implementation of OIDC/OAuth 2.0 in mobile apps, is to replace cached credentials (e.g., password storage). After performing user authentication, tokens are obtained:
- An access token is used to authenticate towards the backend. Access tokens typically only have a limited lifetime.
- A refresh token is used to request new access tokens. These refresh tokens usually have a long lifetime (sometimes indefinite) and allow for de facto creation of long (sometimes infinite) sessions.
The risk of passwords being stolen on a mobile device is exactly the same as the risk of refresh tokens being stolen. Both need to be accessible to the app, in order for the app to present it to a backend. That access tokens only have a limited lifetime is irrelevant, once you obtain the refresh token, you can keep on requesting new access tokens for a long time (sometimes forever).
JWT tokens contain cryptographic signatures, so they must be more secure than ‘plaintext’ tokens? Unfortunately, this is not the case. A JWT token is digitally signed by a backend, not by the app or device (hence it is the backend that authenticates the token, not the app nor the device). Presenting the token is sufficient to gain access. The main reason for using JWT tokens, is to reduce the storage requirements on the backend, allowing for stateless authentication. Instead of storing a list of valid tokens, one can simply validate the signature instead.
Accessing resources and API's
The primary purpose of OIDC and OAuth 2.0 is federated authentication, situations in which you authenticate towards a different organisation as the organisation that holds the resources you are trying to access. Imagine situations where you use a central login (e.g., your work login or a social login) to access a SaaS platform operated by another party, potentially with a client or intermediate system operated by yet another party.
Similarly, this could also be used in mobile apps, where the user – after user and/or app authentication – obtains tokens for accessing (third-party) resources and API’s. After authentication, the app will receive an authorization code, which it can then exchange for the required tokens.
Depending on your mobile app’s architecture, it could very well be that the mobile app does not need to concern itself with OIDC/OAuth 2.0 flows. Typically the app will communicate with one specific backend, which doubles as OAuth 2.0 Client and access the resources and API’s on behalf of the mobile app. In this case, the backend stores and handles the tokens, and not the mobile app itself.
In most cases a regular cookie suffices for keeping short-term sessions alive, to avoid continuously asking the user to authenticate. Regardless of the usage of tokens and/or cookies, the crucial question still remains: how to obtain one?