How to make a custom Username Password Authentication Filter with Spring Security

 

Introduction

Basically I’ll show you how to use Spring Security and how to customize it if you want. First we’ll implement the basic authentication with basic responses and other stuff, and I’ll show you how to customize the login and logout process as you wish (smile)

Simple Authentication

After you added the required dependencies described on Spring’s website, you want to create a WebSecurityConfig class, that tells Spring Security how you want to authenticate your users, and what you want to do

  • after a successful login,
  • an unsuccesful login, and
  • after a successful logout.

Let’s say we have a pretty simple Controller we want to protect with authentication.

 

And the WebSecurityConfig


 

As you see there is a UserService that, for now, has a really simple implementation


By implementing the ‘loadUserByUsername’ function, you tell Spring the password of your user, and the authorities it should grant to the authenticated user. For now authorities is an empty List. Spring will compare your user’s password, and the password form the API. If they match. By default a ‘PlaintextPasswordEncoder’ used by Spring, but later i’ll show you how to encode your passwords (smile)

After you added these lines to your project, you can try out the following actions from your favourite REST Client (I use Postman)

url - behavior - spring password

Reading request body

In the next step we’ll change our application to read the request body instead of the query string.

IMPORTANT!

You can only read the request body’s stream once. If you want to use the data in different services for example, you should cache the body somehow (you can find a lot of solutions if you google it). Let’s assume that we only want to read the body once (smile)

First we need a CustomUsernamePasswordAuthenticationFilter and we have to tell Spring to use our filter instead of the default one.

 

 

This is how our custom filter looks like. It is as simple as it seems, we just have to parse the request body into a Java class, create a token, and then use the default authenticaton method. After we created this class, we only have 2 tasks left. First is to provide our bean, second is to tell Spring to use our filter instead of the default one. To reach this we change out WebSecurityConfig class like this

 

IMPORTANT!

Note the commented lines. After you provided your custom filter, you can no longer use the Spring HttpSecurity builder. If you still use it, you’ll configure the default Filter, not yours!

We tell Spring to use our implementatin by the “addFIlterBefore” function.

After this little modification, the test APIs work the same way, the only difference is that you should provide ‘login’ and ‘password’ params in the POST request body (and not the query string)

Encoding passwords

First we have to change our UserDetailsService a little

 

Like this, our UserService provides a mock user that has an encoded password.

Second we have to change our WebSecurityConfig

As you see, we changed the configureGlobal a little bit, and added a DaoAuthenticationProvider bean. We have only one more thing to do, we have to provide our favourite PasswordEncoder in a separate class, like:

 

After these modifications, the same APIs should work like before. The only difference is on the backend side, we “stored” our users with encrypted passwords, which is nice. (smile)

Summary

As you see, adding a custom authentication is not hard with Spring, the hard thing was to put all of these together. As far as I saw, no one on the internet wanted to customize the login process like I described above. I hope you found this post useful! If you want to take a look at the full example project, just click here. If you want to read more posts like this, keep up with #TeamWanari on social media!

See you later! (smile)

Alex Sükein

Alex Sükein

- Süxy, can you tell me about robust software development Nasa uses?
- Yes. If we have a final exam tomorrow.