Friday, October 6, 2023

How does Remember Me functionality works in Spring Security?

In the last article, You have learned how to enable the remember-me functionality in Spring security and today you will learn how does Remember Me work under the hood. So far, you know that remember-me functionality uses cookie to remember users and allow auto-login (without entering password again), so you might have guessed that spring security provides hooks to generate that cookie as well as process those cookie when an already signed user open the application after the break e.g. after a day or two. As long as cookie is not expired and token is valid i.e. user hasn't changed the password, he should be able to login to your application. 

Spring security supports remember-me functionality in two parts, first, classes and interfaces to generate cookie and second to process that cookie to create an Authentication object for remember-me user. 

How Remember-Me functionality works in Spring Security?

The two most important classes related to remember-me functionality in spring security is RememberMeServices interface and RememberMeAuthenticationFilter class. 

When you enable this functionality by adding in your spring security configuration file or by calling the rememberMe() method on HttpSecurity object, passed to the configure() method, the RememberMeAuthenticationFilter is added into filter chain,

And a TokenBasedRememberMeServices, an implementation of RememberMeServices is created and injected into AbstractAuthenticationProcessingFilter, replacing the no-op NullRememberMeServices

Btw, if you are not familiar with spring security filter chain, I suggest you to join one of these best Spring Security online courses to learn more about it. Anyway, when the user first login into application by clicking the remember-me checkbox you have added into login.jsp page, the request has a remember-me parameter on it. 




When this request reached to the server, it is passed to UsernamePasswordAuthenticationFilter (a subclass of AbstractAuthenticationProcessingFilter) for authentication purpose. After the authentication is successful, this filter invokes the loginSuccess() method of configured TokenBasedRemeberMeServices class. 

This method than checked if remember-me parameter is present in the request, if its present then it extracts the username and password from the Authentications object and creates a token with this information and a time to expire. 

It basically combines username, passwords, expirationtime and a key to create a MD5 hash which is then base-64 encoded along with username and time to expire. This token is then added into the cookie which is sent to the client on login success response. 

Now, let's see what happens when a user tries to access your website after a couple of days. When he does that browser sends the spring security cookie along with HTTP request. 

This time, the request is intercepted by RememberMeAuthenticationFilter class, which checks if there is no current Authentication object in the SecurityContext because that means no user logged in.

After that, this filter calls the autoLogin() method of RememberMeServices interface, which is delegated to TokenBasedRememberMeServices because that's the concrete class which implements this interface. 

This implementation of autoLogin() method tries to parse the incoming cookie into its individual parts e.g. it first decode the token using base-64 encoding algorithm and extracts username, expiry, and the MD5 hash value for authentication. 

After that it retrieves the UserDetails from the UserDetailsService by using the username from the token, recomputes the hashed valued with the retrieved user, and compares it with the arriving one. If you remember the hash is computed using username, password, expiry and a private key. 

If they don't match then an InvalidCookieException is thrown and if they do match then the UserDetails is checked and an Authentication object is created and returned to the Caller. The rest of thing works as in the standard way. 

As they said, one picture is worth a 1000 words so, here is a remember me working diagram which explains whatever I said in this article:

How does Remember-Me functionality works in Spring Security?



That's all about how does remember-me functionality works in Spring security. As I said, it is implemented using a token and a cookie. When you enable this functionality then the relevant classes and filters e.g. RembemberMeAuthenticationFilter and TokenBasedRememberMeService is created and injected into right place. 

They are then responsible for generating token to be passed along cookie and handling the HTTP request with token when user access the website again. 

Even though, remember-me functionality is very convenient for users it also poses security risk, hence you should be careful with that. One strategy is to only provide basic functionality using remember-me service and protect sensitive URL and only allow them after full authentication. 

I'll write more about excluding sensitive URLs from remember-me functionality in next article, but if you can't wait, I suggest you to check the Spring Security MasterClass by Eugen Paraschiv, one of the most comprehensive and advanced course to learn Spring security. 

Thanks for reading this article so far. If you like this article and my explanation of how spring security handles remember-me requests then please share with your friends and colleagues. If you have any question or feedback then please drop a note.

 Other Spring Security tutorials and Resources 
Thanks for reading this article, if you like my explanation of How does RememberMe Functionality in Spring Security works under the hood, then please share this article with your friends and colleagues. If you have any questions about feedback, then please drop a note.

P. S. - If you like to learn from free resources, then you can also check out my list of free courses to learn Spring MVC and Spring Boot online. The list contains some free courses from Udemy, Pluralsight, Coursera, and other resources to learn the Spring framework.

No comments:

Post a Comment