Skip to content
Advertisement

Why is remember-me a lesser authentication then full-authentication in spring-security?

This is a conceptual question about the fact, that authentication has different grades in spring security.

There is a grade for

  1. anonymous authentication also called IS_AUTHENTICATED_ANONYMOUSLY
  2. and remember me authentication IS_AUTHENTICATED_REMEMBERED
  3. the full authentication, when a user just provided his entire credentials and got confirmed aka IS_AUTHENTICATED_FULLY

In the implementation of AuthenticatedVoter#isFullyAuthenticated it is clear, that a full authenticated user cannot be anonymous authenticated or remember-me authenticated.

While I fully understand why we differentiate between IS_AUTHENTICATED_FULLY and IS_AUTHENTICATED_ANONYMOUSLY, I really do not understand why IS_AUTHENTICATED_REMEMBERED is not treated equally to IS_AUTHENTICATED_FULLY.

How I understand remember me:

I understand remember me as authentication using some kind of secret token – using this token we load an existing SecurityContext which already includes the fully authenticated Authentication object written there during the initial full authentication. It is basically restored full authentication in this regard.

Comparing this to the session-login, which has a similar token but considered full-authentication in spring security, why is there a difference between remember-me and session-based?

Question:

Considering that remember-me restored a full-authenticated SecurityContext, the application logic would treat the context the same as it would be just normal full authentication.

If we would have some logic for full authenticated users in the application, it would surely also apply to remeber-me authenticated cases.

Of course, for anonymous authenticated users we often have different decisions to take, so that is why I understand why this is singled out.

Do I understand the concept of remember-me the wrong way or what is the exact reason not counting users remembered as fully authenticated?

Advertisement

Answer

Comparing this to the session-login, which has a similar token but considered full-authentication in spring security, why is there a difference between remember-me and session-based?

Normally you have a lower session timeout than the life span of a remember-me token. According to Spring’s documentation the remember-me token has a life span of 2 weeks as opposed to the session timeout often just defined in minutes.

Remember-me could be thought of being similar to restoring a session that timed out but that would be as insecure as just restoring the security context. Why?

In general you want to apply several security layers and there are some you as an application developer would not of control of (at least not directly), e.g.:

  • There is no guarantee that users don’t share their credentials (uersname/password) so multi-factor authentication might be required.
  • There is no guarantee that an authenticated user steps away from their machine and don’t lock it. In that case someone else could access the application and thus you would want to keep tokens as short-lived as possible. Many applications thus use additional tokens for critical operations, e.g. when I can put products into my cart on Amazon but when I want to place the order I’m required to re-authenticate to make sure it’s actually me.

It’s basically the second risk that remember-me increases: You only can assume a user is still in front of their machine if they are actively using the application so you’d want to make your session timeouts as short as possible to quickly determine a user is inactive (and long-lived enough to maintain a good level of usability).

Remember-me would reactivate an inactive session (or at least the associated security context) and thus here you assume that the user now in front of the machine is the original one. There’s no guarantee of that and hence remember-me authentication can be considered less secure.

OAuth refresh tokens could be considered something similar: you get an access token when the user is successfully authenticated but access token would expire regardless of activity. Then you’d use a refresh token to get a new access token if the session is still active (which doesn’t guarantee the user is or didn’t change).

So in terms of security and not considering authentication options I’d rank them in the following order:

  • access token retrieved by authenticating the user explicitly: use this for critical operations, make them short-lived and don’t provide refresh tokens for those
  • refresh token and access tokens retrieved via a refresh token: basically comparable to session security as refresh tokens life spans often are related to session life spans (if a user doesn’t access a protected resource within time X then both the access and refresh tokens would have expired and the user would need to re-authenticate). Note that refresh tokens should not be shared with the user.
  • remember-me tokens: could be considered a form of long-lived refresh token that is shared with the user
Advertisement