1
votes

Our company is building a mobile app (iOS) which needs to talk to our API, which is secured by OpenIdConnect/OAuth2, using IdentityServer.

My question is, most apps i've used these days ask for the user to login/register once, then never again.

Assuming they are accessing their API's using OAuth2 tokens, how do they achieve this?

OAuth supports offline_access via "refresh" tokens, which allow getting new tokens without the user logging in again. However, they also have an expiry - so given the following scenario:

  1. User creates account, gets access token/refresh token. Access token expires in 1 hour, refresh token in 2 hours.
  2. User is using the app, app gets new access/refresh token in background
  3. User closes app
  4. User comes back the next day

At this point, both the access and refresh token are expired. How do they get a new one, without prompting the user to enter credentials again?

I understanding OpenIdConnect has the concept of identity tokens, and as long as this is active at the server, new access tokens can be fetched without prompting the user again.

So, i can only think of two ways apps do this:

  1. They have background services that run when the app is closed, that keeps getting new access/refresh tokens. Is this possible?
  2. On app start, if the access/refresh tokens are expired but the identity token (session) is still active, do a silent trip to the auth server (hidden web view?) which will automatically get a new set of tokens.

2 seems possible, but this would only work in the browser-based OAuth flows (implicit, authorization code) where there is SSO/cookies involved.

For apps that have a native login (U/P in app), they are most likely using the Resource Owner Password Credentials flow, which doesn't support SSO (no browser, no cookies). So how would they get new tokens, unless they are storing a reversible username/password in the client app itself, then passing them to the Auth Server again to get new tokens?

What am i missing?

Thanks in advance.

2

2 Answers

3
votes

The apps typically use long-lived refresh tokens that don't expire in 30 mins as you suggest but may live for many weeks/months until the user is forced to login again. Making the lifetime of the refresh token the same as the access token defeats the purpose as the refresh token should be the token that can be used to get a new access token when the old one expires. Refresh tokens typically outlive the user authentication session at the provider.

0
votes

We have a similar situation with our Nativescript Angular App. We use OAuth 2 with PKCE for our authentication process but my team is fairly new to the world of mobile development.

From my research it would seem best practice suggests the lifespan of the refresh token should be anywhere between 2 weeks and 2 months. Currently our access token lifespan is set to 2 minutes and our refresh token lifespan is 30 mins. This means our users have to login every 30 mins using their username and password which isn't ideal for UX and we've received a lot of criticism for it.

Our login page uses a WebView so we considered also trying to auto-populate the form fields with a securely stored version of the username and password but then realised this can't really be done and isn't great for security.

So to improve the login process and make it more seamless, we're looking to setup face/touch ID with a pin code fallback. This means we'll have to push the lifespan of the refresh token to say 2 months or as long as possible — this seems like the best approach moving forward.

That said, the other problem is we also have a website which uses the same authentication server so if we change the Keycloak settings it'll change it also for the website as well which will create more work for the web team.

So my question is should we be using a separate authentication server just for mobile access?