Security – Is Saving User/Password and Getting Token Automatically Safe?

asp.netmobileSecurityxamarin

Suppose I have a REST API backend and it is used by a mobile app. Authentication is based on tokens (JWT) with expiration time. Mobile app user does not want to enter credentials so often, even for weeks. In other side I think token must not have expiration time more than 24 hours or so. If I do not include token invalidation on backend (which imposes a session management on a REST server) what options are available and what is cons and pros of each one?

What about to force mobile app to login automatically behind the eyes of the user if token is expired? In this way user and password must be saved somewhere in mobile app that I'm not sure if it is a good idea.

Our back-end in ASP.NET Core Web API and current mobile app is Xamarin.IOS.

Best Answer

No, it is not a good idea to store the user's password. Saving the password is easy to get wrong and creates another attack vector (storage on mobile device). Though they shouldn't, many users use the same password for multiple services. So a compromise of their password for your service could also expose their data for other services. You can't really protect the user from their bad habits, but storing a password in your app is very avoidable.

What you probably want is a refresh token. This concept is a part of the OAuth2 spec. These can be used to keep the user "logged in" without keeping their password or requiring long token expirations. You can also effectively "log off" a user by deauthorizing their refresh token, provided you are using short access token lifetimes.

The way it works:

  1. User authenticates with password to the auth service (not your API)
  2. App receives access token and refresh token
    • Access token lasts a short time, say 5 minutes
    • Access token is only for calling your API
    • Refresh token is valid for a long time, say 1 month
    • Refresh token is only for calling auth service to request new access token
  3. App uses access token to call your API
  4. Access token expires (frequently)
  5. App uses the refresh token to get a new access token from the auth service
  6. Later, admin "logs user out" by revoking the refresh token
  7. Within 5 minutes (access token lifetime)
    • Access token expires
    • App will be unable to obtain a new access token b/c refresh token denied
    • User will have to re-enter password to get new tokens

If you aren't already, I would highly recommend externalizing authentication and authorization (not implementing it yourself). There are several cloud providers which do this as a service (e.g. Auth0). For .NET Core there is also IdentityServer4 which you can host yourself. I do not have experience with ASP.NET Core Identity, but at cursory glance it does not automatically come with OpenID Connect and OAuth2 features. You have to do integration steps with other providers (like IdentityServer4) to get that.

Related Topic