SpringSecurity is a security framework specifically for Spring-based projects that makes full use of dependency injection and AOP for security control. In many large enterprise systems, permissions are the core, and a system’s good or bad all depends on whether permissions are flexible and granular. While earlier versions of SpringSecurity required a lot of XML to configure, integrating the SpringSecurity framework based on SpringBoot has been a relative rebirth, ridiculously simple.

The SpringSecurity framework has two concepts: authentication and authorization, authentication can access the system users, and authorization is the resources that users can access. Let’s briefly explain SpringBoot’s support for SpringSecurity security framework.

Objective in this chapter

The SpringSecurity security framework is used in the SpringBoot project to implement user authentication and authorized access.

Build the project

We used IntelliJ IDEA tool to create a SpringBoot project with JPA, Security, Druid, MySQL and other dependencies pre-added. The project structure is shown in Figure 1 below:




Figure 1


We will first configure the database access configuration by copying the application.yml configuration file from the previous chapter (Chapter 13: SpringBoot Actual SpringDataJPA) into the resources directory of this chapter, as shown in Figure 2 below:




Figure 2


Users and Roles

After the database connection configuration is completed, we start to create three tables that need to be used in this chapter, user table, role table, user role association table, a user has multiple roles! The structure of the user table is shown in Figure 3 below:




Figure 3


Our user table structure has only three fields, so we won’t go into too much detail here because we’re just demonstrating our security framework. The structure of our role information table is shown in Figure 4 below:




Figure 4.


Because one user has multiple roles and one role can be applied to multiple users, we use the associated table to configure the relationship. The structure of the associated table of user roles is shown in Figure 5 below:




Figure 5


Now we create the corresponding entities according to the user information table and role information table, as shown in Figure 6 and Figure 7 below:




Figure 6.


As you can see, our UserEntity implements the UserDetails interface. UserDetails is the user authentication interface provided by the SpringSecurity authentication framework (we need to use UserEntity for custom user authentication). Orities need to implement the Getathorities approach, adding the list of roles we defined to the authorized list.




Figure 7.


You can see that we have added list support for roles in our user entities and added @manytomany relationship annotations. When we query a user, SpringDataJPA automatically queries the user’s role List of user_roles from the local associated table into a List named ROLES.

Populate test data

We add several corresponding data to the user table, role table and association table. The SQL script is shown in Figure 8 below:




Figure 8.


The initialized SQL script has been added to the Resources directory of this chapter, where the source code will be downloaded at the end of this chapter.

Configure JPA access data

Create the UserJPA interface from the created UserEntity and inherit the JPARepository interface. Add a method to UserJPA that queries by user name, as shown in Figure 9 below:




Figure 9.


We can see that I have added a findByUsername method to the UserJPA interface in Figure 9. This method is actually a SpringDataJPA rule. We write it this way and JPA thinks we need to query by username. And automatically uses a value with a parameter index of 0 (SpringDataJPA method queries will be reflected later in the SpringDataJPA core technology).

Custom SpringSecurity user authentication

The above configuration is almost complete. Now we implement the UserDetailsService interface in SpringSecurity to complete the logic of customizingquery user, as shown in Figure 10 below:




Figure 10.


As you can see from the definition in Figure 10, implementing the UserDetailsService interface requires loanUserByUsername rewriting. We use the findByUsername method in UserJPA to read the user from the database and use the user as the return value of the method.

Configuration SpringSecurity

Custom user authentication has been written. Now we need to configure the SpringBoot project to support the SpringSecurity framework, as shown in Figure 11:




Figure 11.


In the first sentence, we only use CSRD. After springSecurity4.0, CSRD interception is enabled by default. If you need to configure this, please add the following configuration in the form form:




Figure 12


We have configured the login page 127.0.0.1:8080/login request address and the login error page /login? Error is not intercepted by SpringSecurity. Let’s write the login JSP page. We didn’t add JSP dependencies when we built the project. Let’s modify pom.xml to add JSP dependencies, as shown in Figure 13 below:




Figure 13


We modify the application.yml configuration file to add the page configuration for the JSP, as shown in Figure 14 below:




Figure 14


Now let’s simply create a login.jsp page and add a simple form submission to the page. Our form submission address is already defined by SpringSecurity. After version 4.0, the login address will be /login. Of course, this /login is not the loginPage address we configured above. This address is not accessible by direct access. You must use Post to access the login.jsp page as shown in Figure 15 below:




Figure 15


To configure a simple SpringBoot MVC controller jump, add a configuration class called MVCConfig that inherits the WebMvcConfigurerAdapter class and override the addViewControllers() method to add path access. You can access our login.jsp with the /login form of Get, as shown in Figure 16 below:




Figure 16


Now that the SpringSecurity configuration is complete, we will add an IndexController to test whether our SprinySecurity framework is working. We have configured the SprinySecurity framework above. If only /login can be accessed without logging in, So it’s not feasible for us to access /index directly. SpringSecurity redirects us directly to our configured loginPage, as shown in Figure 17:




Figure 17


Run the test

To start the project, visit /index to see what the interface looks like, as shown in Figure 18 below:




Figure 18


As we said, when we access /index without logging in, we are directly redirected to the login page by the security framework, so after logging in, we can access /index and see the interface output, as shown in Figure 19 below:




Figure 19


We can see the effect of the interface. We can access the data returned by the index path correctly, proving that our security framework is working.

Role of judgment

We have created the role table at the beginning of this article. Now we are going to display different content according to the role after the user logs in successfully. Before that, we need to add the JSTL tag library provided by SpringSecurity. We modify the POM.xml configuration file to add dependencies as shown in Figure 20 below:




Figure 20


Next we create main.jsp, import the SpringSecurity tag library into the JSP page, and determine the output based on the role, as shown in Figure 21 below:




Figure 21


In main.jsp, we identify the roles of super administrator and ordinary user and output different content according to different roles. Now we restart the project and access 127.0.0.1:8080/main to view the output content of the interface, as shown in Figure 22 below:




Figure 22


Our interface doesn’t output anything. Why is that?

SpringSecurity does not support Chinese matching, so we cannot directly use the Chinese name of the role as a criterion. Let’s modify the ROLES information table to add an identity field, as shown in Figure 23 below:




Figure 23


Below we add the field within the RoleEntity entity, as shown in Figure 24 below:




Figure 24


Most importantly, the role authorization is added to our UserEntity based on RoleName, so we need to change it to flag, as shown in Figure 25 below:




Figure 25


Finally, we modify main.jsp and change hasRole to the corresponding flag field value, as shown in Figure 26 below:




Figure 26


In the figure above, ROLE_USER and ROLE_ADMIN are the corresponding data added in the roles table, which are also the authorized flag field values. Let’s restart the project and log in to 127.0.0.1:8080/main to view the interface output as shown in Figure 27 below:




Figure 27


The interface outputs two messages for you, which is correct because we have added two roles for the admin user in the USER_Roles table. Let’s change the user_roles table structure to delete the association for common users, and then access 127.0.0.1:8080/main. The interface output looks like figure 28 below:




Figure 28


We wonder, why hasn’t the data changed? Since SpringSecurity caches our user data and role data into the framework, let’s restart the project and see the interface output as shown in Figure 29:




Figure 29


This time the output is correct.

conclusion

This chapter mainly explains how to use SpringSecurity as a security framework in the SpringBoot project, and judge the output of the interface through the JSTL tag library provided by SpringSecurity, and if the modification of the user’s permission does not take effect in real time, But we need to log out of the user again to take effect.

The code for this chapter has been uploaded to the code cloud, as well as the SQL:

SpringBoot source code address: gitee.com/hengboy/spr…

SpringCloud source code address: gitee.com/hengboy/spr…

For SpringBoot related articles, visit: Directory: SpringBoot learning directory

For a series of QueryDSL articles, visit the QueryDSL Generic Query Framework learning directory

For articles in the SpringDataJPA series, visit: Directory: SpringDataJPA Learning directory

SpringBoot related articles please visit: directory: SpringBoot learning directory, thank you for reading!

Welcome to join QQ technical exchange group, common progress.




QQ technical exchange group