Spring Security 6. Database Based Authorization and Authentication

Hello. My name is Kirill, I am a Java developer. Despite the fact that I have been working in the company for a year now, I still try to find time for my own projects, with the help of which I master the technologies and approaches that interest me. It was on this project that I decided to figure out how database-based authorization and authentication works in Spring Security 6. There are a lot of changes compared to previous versions. The examples from the documentation do not fully answer all questions, and no matter how hard I tried, I could not find materials in Russian on this topic. I collected information from various foreign sources piece by piece. Now I will share with you what I found.

I think that most readers know what authorization and authentication are, and how they differ from each other. But in case students read the article, I will roughly generalize that authorization is the cutting off of those who do not generally have access to the resource. Authentication – distribution of capabilities (rights, permissions) for authorized users. Authentication is based on the roles of the registered user and other properties that we will touch on later.

The main problem is that since Spring Security 5.7.0 the WebSecurityConfigurerAdapter class has been deprecated and cannot be used in future versions. Most of the currently existing guides rely on the inheritance of this class.

In my material, I will bring to your attention a minimal skeleton of a service with authorization and authentication based on a database, with several endpoints, access to which is regulated by roles and access levels. The skeleton will be truly minimal, so as not to overload the reader with unnecessary information and logic, while fully introducing the concept. In the future, you can expand this skeleton by adding your own functionality and adapting it to your tasks.

So, first, let's create a new project using Spring Initializr.

Creating a Project

Creating a Project

Everything is standard here. We select any modern version of Spring, build via Maven, and enter the metadata. Additionally, we connect Spring Web, Spring Data JPA, MySQL Driver (in the example I will use MySQL, but you can use any database at your discretion) and Lombok (I am more comfortable with it).

Next, we will create a database with the fields we need. The required fields for our project are name, password and role. In the password column we write some simple password (for easier remembering and testing), encoded in Bcrypt password encoder. I have 1234 for everyone, encoded with complexity 5 (this must be remembered and applied in the future, otherwise authorization will not work).

My test base looks like this

My test base looks like this

We open the project and register our database in Application Properties.

Then I like to run it and check if everything works. Since we haven’t written the SecurityConfig class yet, let’s go by user name and take the password from the logs.

Now we will write the User entity, with the help of which we will convert users from the database into objects, as well as the UserRepository interface, which extends JpaRepository..

Entity User

Entity User

UserRepo

UserRepo

Next, we will create the TestController class, where we will register several endpoints that can be accessed according to the user access level:

  • welcome – the page will be shown to everyone, even without authorization;

  • users – page for those who have the USER role in the database;

  • admins – for all admins;

  • all – for everyone, but after authorization.

The simplest controller with distribution of endpoints by roles

The simplest controller with distribution of endpoints by roles

There will be no services with detailed business logic in our example, because, as I mentioned earlier, we are writing a simple, minimal skeleton, so I don’t see any point in overloading the readers’ understanding abilities.

To configure the operation of SpringSecurity, we will create a SecurityConfig class, where we will describe the principles of authorization and authentication for each endpoint, set UserDetailService, PasswordEncoder and other properties.

The most important class when working with Spring Security

The most important class when working with Spring Security

We are writing a custom MyUserDetailsService that extends UserDetailService and implements the loadUserByUsername method…

… and the associated custom MyUserDetails, which transfers our “user” from the database into a “user” understandable by SpringSecurity. Here we extend the standard UserDetails and override all its methods.

The GetAuthorities method is written this way in case someone from the database has several roles

The GetAuthorities method is written this way in case someone from the database has several roles

We launch the project and test the endpoints. As a result, the “welcome” page is entered without authorization, all registered users can access the “all” page, and users with the USER and ADMIN roles have access to the “users” and “admins” pages, respectively.

As I said earlier, in the future the functionality of the skeleton can be expanded, business logic can be attached to it, more interesting endpoints can be added and created, the user base can be complicated and the SecurityFilterChain architecture can be changed. It’s easy to embed this foundation into any existing project, slightly modifying it to suit your own conditions. (If it’s interesting, I’ll show you how I built it into my electronic library project).

If you have any questions, I will be glad to answer them in the comments. I will also be glad to receive feedback from more seasoned and experienced developers.

Project repository Here.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *