Detailed WebSecurityConfigurerAdapter

This article will detail the WebSecurityConfigurerAdapter in security.

Today we are going to further learn how to customize Spring Security. We have mentioned WebSecurityConfigurerAdapter many times, and we know that the automatic configuration in Spring Boot is actually the Spring Boot Web Security imported through the SecurityAutoConfiguration general configuration class under the automatic configuration package. Configuration class SpringBootWebSecurityConfiguration to configure.

SpringBootWebSecurityConfiguration source code

Common method
WebSecurityConfigurerAdapter class diagram

Common configuration
Let’s paste the common configuration of WebSecurityConfigurerAdapter in the project

I believe someone has noticed that I have overridden (@Override) three configure methods in the WebSecurityConfigurerAdapter above. We generally customize our security access policy by customizing these three methods.

Authentication Manager Configuration Methods
AuthenticationManagerBuilder (Authentication Manager Builder)

void configure(AuthenticationManagerBuilder auth) is used to configure AuthenticationManager. To put it bluntly, it manages all UserDetails related, including PasswordEncoder passwords, etc. If you are not clear, you can find out through UserDetail in Spring Security. This article does not do a specific analysis and explanation of AuthenticationManager, and there will be a special article about this later.

Common usage

Core filter configuration method
WebSecurity (WEB security)

void configure(WebSecurity web) is used to configure WebSecurity . And WebSecurity is based on Servlet Filter to configure springSecurityFilterChain . The springSecurityFilterChain is delegated to the Spring Security core filter Bean DelegatingFilterProxy . The related logic can be found in WebSecurityConfiguration. We generally don’t customize WebSecurity too much, and use more of its ignoring() method to ignore Spring Security’s control of static resources.

Security filter chain configuration method
HttpSecurity (HTTP request security processing)

void configure(HttpSecurity http) This is what we use the most to configure HttpSecurity . HttpSecurity is used to build a security filter chain SecurityFilterChain . The SecurityFilterChain is eventually injected into the core filter. HttpSecurity has many configurations that we need. We can use it to customize the security access policy. So we have a separate chapter to explain this stuff.

HttpSecurity configuration
HttpSecurity is the focus of the following articles, and we will actually operate it to achieve some practical functions. So this article will focus on it.

HttpSecurity class diagram

Default Allocation

The above is the default configuration of Spring Security in Spring Boot. Through the above configuration, your application has the following functions:

  • All requested access requires authorization.
  • Use the form form to log in (the default path is /login), which is the login page we saw in the previous articles.
  • Prevent CSRF attack, XSS attack.
  • Enable HTTP Basic Authentication

Summary of this article
This article introduces the knowledge and content related to WebSecurityConfigurerAdapter in detail, and will introduce the knowledge related to HttpSecurity in detail later, which is also the most used place in normal development.

The difference between BIO, NIO, and AIO

Many articles just throw a bunch of definitions and some vivid examples when talking about BIO, NIO, and AIO. Seems to be well understood. However, the most basic essential principles are not revealed. If you do not start from the principle of IO, it is difficult to understand the difference between the three. In this article, you will get: the performance difference between synchronous/asynchronous + blocking/non-blocking; the difference between BIO, NIO, and AIO; understanding and implementing multiplexing when NIO operates Sockets; at the same time, master the bottom and core operation skills of IO.

IO principle in Java

First of all, IO in Java depends on the operating system kernel. The IO reading and writing in our program actually calls the two system calls of read and write in the operating system kernel.

How does the kernel interact with IO?

  1. The network card receives the network data transmitted through the network cable, and writes the network data to the memory.
  2. 2When the network card writes the data into the memory, the network card sends an interrupt signal to the cpu, and the operating system can know that there is new data coming, and then process the data through the network card interrupt program.
  3. Write the network data in the memory to the receive buffer of the corresponding socket.
  4. After the data in the receive buffer is written, the application starts data processing.

A simple example of socket code corresponding to abstraction to java is as follows:

It can be seen that this process is very similar to the network IO of the underlying kernel, which is mainly reflected in accept() waiting for a request from the network, and then the bytes[] array is used as a buffer to wait for the data to be filled before processing. The difference between BIO, NIO, and AIO is whether these operations are synchronous or asynchronous, blocking or non-blocking.

So we introduce the concepts of synchronous and asynchronous, blocking and non-blocking.

Synchronous and Asynchronous

Synchronization and asynchrony: Synchronization means that when the completion of a task needs to depend on another task, the dependent task can be completed only after waiting for the dependent task to complete. This is a reliable task sequence. Either all successes succeed, and all failures fail, and the status of the two tasks can be kept the same. Asynchronous means that there is no need to wait for the dependent task to complete, but only to notify the dependent task of what work to complete, and the dependent task is executed immediately, as long as the entire task is completed by itself. As for whether the dependent task is actually completed in the end, the task that depends on it cannot be determined, so it is an unreliable task sequence. We can use phone calls and text messages to describe synchronous versus asynchronous operations well.

Synchronization and asynchrony refer to whether each method in an execution flow must depend on the completion of the previous method before it can continue to execute. Suppose our execution process is: method one and method two in turn.

Synchronization means that once the call has started, the caller must wait until the method call returns before continuing the subsequent behavior. That is, method 2 must wait until method 1 is executed before it can be executed.

Asynchronous means that the call returns immediately, and the caller can continue the subsequent behavior without waiting for the execution of the code in the method to end. (The code in the specific method may be called back after it is executed by another thread.) That is, when method 1 is executed, it is directly handed over to other threads for execution, and it is not executed by the main thread, so it will not block the main thread, so method 2 does not have to wait until method 1 is completed to start execution.

Synchronization and asynchrony focus on whether the executor of the method is the main thread or another thread. The main thread needs to wait for the method execution to complete, and other threads do not need to wait for the method call to return immediately, and the main thread can directly execute the next code.

Synchronous and asynchronous is to achieve efficiency difference from the coordination between multiple threads.

Why do you need asynchrony? The author believes that the essence of asynchrony is to solve the blocking of the main thread, so many discussions on the Internet have made four combinations of synchronous asynchronous and blocking non-blocking. One of them has the situation of asynchronous blocking. If asynchronous is also blocking? So why do you want to perform asynchronous operations specifically?

Blocking and Non-Blocking
Blocking and non-blocking: Blocking and non-blocking are mainly in terms of CPU consumption. Blocking means that the CPU stops and waits for a slow operation to complete the CPU before completing other things. Non-blocking means that the CPU does other things while the slow operation is executing, and when the slow operation is completed, the CPU then completes the subsequent operations. Although the non-blocking method on the surface can significantly improve the utilization of the CPU, it also brings another consequence that the thread switching of the system increases. Whether the increased CPU usage time can compensate for the switching cost of the system needs to be carefully evaluated.

Blocking and non-blocking refer to whether to do nothing in place when a single thread encounters a synchronous wait.

Blocking means that after encountering a synchronization wait, it has been waiting for the synchronization method to complete the processing in place.

Non-blocking refers to encountering synchronous waiting, not waiting in place, do other operations first, and then observe whether the synchronization method is completed after a time interval.

Blocking and non-blocking concern whether the thread is waiting in place.

The author believes that blocking and non-blocking can only be combined with synchronization. Asynchronous is naturally non-blocking, and this non-blocking is for the main thread. (Some people may think that putting a blocking operation in an asynchronous method is asynchronous blocking, but think about it, it is precisely because it is a blocking operation that it is put into an asynchronous method, do not block the main thread)

Example to explain
Haidilao is delicious, but there are often queues. Let’s take this example from life to explain.

Customer A went to eat Haidilao and just sat and waited for an hour before eating hot pot. (BIO)
Customer B went to eat Haidilao. He saw that he had to wait for a long time, so he went to the mall, and every time he went shopping for a while, he ran back to see if he was in line. So he ended up shopping and eating Haidilao. (NIO)
Customer C went to eat Haidilao. Since he is a senior member, the store manager said, you can go to the mall to play casually, and I will call you immediately when there is a seat. So customer C doesn’t have to sit and wait, and don’t have to run back every once in a while to see if they can wait, and finally eat Haidilao (AIO)
Which way is more efficient? Is it obvious at a glance?

BIO is a traditional package. It is implemented based on the stream model. The interaction method is synchronous and blocking. That is to say, when reading the input stream or output stream, the thread will be blocked until the read and write actions are completed. There, calls between them are in a reliable linear order. Its advantage is that the code is relatively simple and intuitive; the disadvantage is that the efficiency and scalability of IO is very low, and it is easy to become an application performance bottleneck.

The full name of BIO is Blocking IO, which is the traditional IO model before JDK1.4, and itself is a synchronous blocking mode. After the thread initiates an IO request, it keeps blocking the IO until the buffer data is ready, and then goes to the next step. For network communication, it is a request-response method. Although the upper-layer application development is simplified, there is a huge bottleneck in terms of performance and reliability. Imagine if each request needs to create a new thread for special processing, then in high In a concurrent scenario, machine resources are quickly exhausted.

NIO is the java.nio package introduced in Java 1.4. It provides new abstractions such as Channel, Selector, Buffer, etc. It can build multiplexed, synchronous non-blocking IO programs, and at the same time provides high-performance data operations that are closer to the underlying operating system. Way.

NIO, also called Non-Blocking IO, is a synchronous non-blocking IO model. After the thread initiates an io request, it returns immediately (non-blocking io). Synchronization means that you must wait for the data in the IO buffer to be ready. Non-blocking means that the user thread does not wait for the IO buffer in place. You can do some other operations first, but you need to poll regularly to check whether the IO buffer data is ready. .

NIO in Java means new IO. In fact, it is NIO plus IO multiplexing technology. Ordinary NIO is thread polling to see if an IO buffer is ready, while new IO in Java refers to threads polling to see which ones are ready in a bunch of IO buffers, which is an idea of ​​IO multiplexing . In the IO multiplexing model, the task of checking whether the IO data is ready is handed over to the system-level select or epoll model, which is monitored by the system to reduce the burden on user threads.

NIO mainly integrates three technologies: buffer, channel, and selector. Data is obtained through zero-copy buffer, and each client registers on the selector (multiplexer) through channel. The server continuously polls the channel to obtain information about the client. There are four status flags on the channel: connect, accept (blocking), read (readable), and write (writable). Follow up with the identification. So a server can receive an infinite number of channels. No need to open a new thread. Greatly improved performance.

AIO is a package introduced after Java 1.7. It is an upgraded version of NIO. It provides an asynchronous non-blocking IO operation mode, so people call it AIO (Asynchronous IO). Asynchronous IO is implemented based on events and callback mechanisms, that is, application operations. After that, it will return directly and will not be blocked there. When the background processing is completed, the operating system will notify the corresponding thread to perform subsequent operations.

AIO is a true asynchronous non-blocking IO model. In the above NIO implementation, the user thread needs to poll regularly to check whether the IO buffer data is ready, which occupies the application thread resources. In fact, polling is equivalent to blocking, and does not really liberate the current thread, because it still needs to query which IO ready. The real ideal asynchronous non-blocking IO should let the kernel system complete, and the user thread only needs to tell the kernel that when the buffer is ready, notify me or execute the callback function I handed you.

AIO can perform real asynchronous operations, but it is more complicated to implement. There are very few operating systems that support pure asynchronous IO. Currently, windows are implemented by IOCP technology, while on Linux, the bottom layer is still implemented by epoll.

Implementing Permission Management System Based On Spring Security

Slightly more complex background systems will involve user rights management. What are user rights? My understanding is that permission is the centralized management of data (the entity class of the system) and the operations that can be performed on the data (addition, deletion, search, and modification). To build a usable permission management system, three core classes are involved: one is the user User, the other is the role, and the last is the permission Permission. Next, this article will introduce how to build an interface-level permission management system step by step based on Spring Security 4.0.

  1. Related concepts
    Permission = Resource + Privilege
    Role = a set of low-level permissions
    User = collection of roles (high-level roles)
  2. Spring Security’s maven dependencies
    Although the Spring Boot version has reached 2.0, some pits were found when it was used before, so it is recommended to use the relatively stable version 1.5 for the time being.
  1. Define the permission set of the system
    Permissions are a collection of resources and the operations that can be performed on them. For our system, almost all entity classes can be regarded as a resource, and the common operations are adding, deleting, checking, and modifying four categories. Of course, according to our actual business needs, there may be other special operations, such as ours here Added an action to import users. Here is a brief list of two basic permission sets:

In the definition of permissions, the key is the key of resourceId and privileges, and the combination of the two will be used to judge the user’s permissions later. I use the form of resourceId-privilege here to uniquely represent an operation on a resource.

  1. Role-related operations
    The resource and operation permission collection class defines JsonPermissions:

The role class defines Role:

  1. Assign roles to users
    The Spring Security framework provides a basic user interface UserDetails, which provides basic user-related operations, such as obtaining username/password, whether the user account has expired, and whether user authentication has expired, etc. We need to implement this when we define our own User class. interface.
  1. Create initial roles and super administrators for the system
    If we impose access restrictions on all interfaces of the system, who will log in to the system as the initial user and create other users? Therefore, we need to define the initial role and initial user of the system, and automatically enter the initial role and initial user into the system when the system starts, and then use the initial user to log in to the system to create other business-related users. Define the super administrator role of the system: roles.json

Defines the initial admin user for the system: users.json

  1. Load system initialization role and user data
    When the system is deployed, the initialization roles and users of the system need to be automatically loaded into the database, so that they can be used for normal login. Use the @Component and @PostConstruct annotations to automatically import initial roles and users at system startup.
  1. Implement your own UserDetailsService
    Customize user information in UserDetailService, and set all Permissions related to user role role to Authorities of Authentication for PermissionEvaluator to judge user permissions. Note that the form of resourceId-privilege is used here for splicing and storage. My user information here is stored in the MongoDB database, or it can be replaced with other databases.

9.Config UserDetailsService

  1. The back-end interface implements access restrictions based on permissions
    Add the PreAuthorize annotation to the interface method that requires access restrictions. In this annotation, we can use a variety of verification methods, the more common ones are hasPermisson and hasRole. Similar to PreAuthorize, there is the PostAuthorize annotation. It is also better to understand from the literal meaning that PreAuthorize performs verification before accessing the interface, and PostAuthorize performs verification when the result is returned after accessing the interface.

By analogy, corresponding access restrictions can be added to the interfaces that need to restrict user access.

  1. Implement your own PermissionEvaluator
    After adding the PreAuthorize annotation to the interface method, you also need to implement your own PermissionEvaluator. Spring Security will verify the validity of the resource that the currently logged-in user is accessing and the operations performed on the resource in the hasPermission() method.
    Note that the targetDomainObject here is the resourceId we defined before, and the permission is the privilege. When verifying, it should be combined into a format consistent with the format stored in the UserDetailsService. Here we use – dash to connect.
  1. Annotation support
    After implementing PermissionEvaluator, the annotation of globalMethodSecurity must be added, otherwise the permission judgment added on the interface will not take effect. Add this annotation to the inherited class of SpringBootServletInitializer to enable method security.
  1. Access test: 403
    Since the user I am currently logged in has not set the role and access rights for it, I do not have access to the list interface, and the following 403 error occurs when I forcibly access it.
  1. Front-end pages implement personalized pages according to permissions
    It doesn’t end when the backend implements interface-level access restrictions. For the part of the user-visible interface, users with different roles should see different interfaces according to their roles when they log in to the system. Our current experience is that after the user logs in successfully, the user’s permission list is returned to the front-end, and then the front-end judges the permissions. If there is no permission, the corresponding button or function module is hidden. Through the combination of front and back ends, users can only see the operation interface and data within the scope of their permissions. At the same time, even if some users directly modify the interface parameters to obtain data, they will be judged twice at the back end. Make sure that users can see their own data and can only perform operations within the scope of their authority!

Java Several Methods Of Converting Between Map and Object

Java Json And Object Conversion

1.Java object to JSON object

2.Java object to JSON string

3.JSON object to JSON string

4.JSON object to java object

5.json string to JSON object

6.JSON string to Java object

7.JSON string to list

Interview Question About Spring Cloud Context, You Can Answer Like This

Spring cloud, I believe everyone is familiar with it. Spring cloud is a cloud application development tool based on Spring boot; Spring boot focuses on a single individual that is fast and easy to integrate.

So the question is, what is the context in the Spring cloud monomer?

First of all, let’s recall the application context of Spring. What is the application context? It can be simply understood that it is a container object that puts the objects you need Spring to manage for you into the container. The application context is an abstract representation of the Spring container, and our common ApplicationContext is essentially a powerful interface that maintains the bean definition and the cooperative relationship between objects. The core of Spring is the container, and the container is not unique. The framework itself provides many container implementations, which are roughly divided into two types: one is the less commonly used BeanFactory, which is the simplest container and can only provide basic DI function; another is the application context derived from inheriting the BeanFactory, and its abstract interface is the ApplicationContext we mentioned above, which can provide more enterprise-level services, such as parsing configuration files, etc., which is also the application context. The most common use case for instance objects. With the context object, we can register objects that need to be managed by Spring with the container. For the context abstract interface, Spring also provides us with multiple types of container implementations, which can be selected in different application scenarios:

  • AnnotationConfigApplicationContext: Load context definitions from one or more java-based configuration classes, suitable for java annotations
  • ClassPathXmlApplicationContext: Load context definitions from one or more xml configuration files under the classpath, suitable for xml configuration
  • XmlWebApplicationContext: Load context definitions from one or more xml configuration files under the web application, suitable for xml configuration
  • FileSystemXmlApplicationContext: Load context definitions from one or more xml configuration files under the file system, that is, load xml configuration files in the system disk
  • AnnotationConfigWebApplicationContext: specially prepared for web applications, suitable for annotation methods

In this way, we only need to configure the managed objects (we call them beans in Spring) and the collaboration relationship between beans, load the configuration into the IOC container through the application context, and let Spring manage the objects for us. When the time comes, you can get the bean from the container, because the container can provide the object management service you want for your program.

So in fact, there is a concept of “bootstrap context” in a Spring cloud application, which is the parent context of the main application. The bootstrap context is responsible for loading configuration properties from the configuration server, as well as decrypting properties in external configuration files. Unlike the main application, which loads properties in the application, the bootstrap context loads properties in the bootstrap. Properties configured in bootstrap have higher priority, so they cannot be overridden by local configuration by default.

If you want to disable the bootstrap process, set

Application scenarios of bootstrap configuration files:

  • When using the Spring Cloud Config configuration center, you need to add configuration properties connected to the configuration center in the bootstrap configuration file to load the configuration information of the external configuration center
  • Some fixed properties that cannot be overridden
  • Some encryption/decryption scenarios

The application configuration file is mainly used for automatic configuration of Spring Boot projects

OK, the context is over.

Spring Boot gets the file under java resources

Spring Boot gets the files under java resources Springboot gets the directories under the resources directory (for example: get the template directory under the resources directory):
method 1:

Method 2:

Latest 20 Spring Boot Interview Questions That I Often Ask Candidates

I interviewed some people who said on their resumes that they were familiar with Spring Boot, or that they were learning Spring Boot. When I asked them, they only stayed at the stage of simple use, and many things were not clear, which also made me disappointed with the interviewees.

Below, I will summarize some Spring Boot interview questions that I often ask candidates. I hope they will help you.

1. What is Spring Boot?

Spring Boot is a sub-project of Spring open source organization. It is a one-stop solution for Spring components. It mainly simplifies the difficulty of using Spring, saves heavy configuration, and provides various initiators for developers to get started quickly.

2. Why Spring Boot?

Spring Boot has many advantages, such as:

Independent operation

Simplify the configuration

Automatic configuration

No code generation and XML configuration

Application of monitoring

The easier

With all these advantages, why not use Spring Boot?

3. What are the core configuration files of Spring Boot? What’s the difference?

The core configuration files for Spring Boot are the Application and Bootstrap configuration files.

Application configuration file This is easy to understand and is mainly used for automatic configuration of Spring Boot projects.

The bootstrap configuration file can be used in the following scenarios.

When you use Spring Cloud Config to configure the configuration center, you need to add the configuration properties connected to the configuration center in the bootstrap configuration file to load the configuration information of the external configuration center.

Properties that are fixed and cannot be overridden;

Some encryption/decryption scenarios;

4. What are the formats of Spring Boot configuration files? What’s the difference?

.properties and.yml, the main difference between them is the writing format.



In addition, the. Yml format does not support @propertysource annotation import configuration.

5. What are the core annotations for Spring Boot? Which notes are it mainly composed of?

The annotation above the Boot class is @SpringBootApplication, which is the core annotation of SpringBoot. The main combination contains the following three annotations:

6. What are the ways to enable Spring Boot?

1) Inherit the spring-boot-starter-parent project

2) Import the spring-boot-Dependencies dependencies project dependencies

7. Does Spring Boot need a separate container to run?

You don’t need it, Tomcat/ Jetty containers are built in.

8.What are the ways to run Spring Boot?

1) Package with command or put in a container to run

2) Run the Maven/ Gradle plugin

3) Run the main method directly

9.What is the principle of Spring Boot automatic configuration?

The @enableAutoConfiguration, @Configuration, and @conditionalonClass annotations are at the heart of the auto-configuration, which must first be a Configuration file and then be automatically configured based on whether the class is present in the classpath.

10.What is the directory structure of Spring Boot?


This directory structure is the prevailing and recommended practice, while the @SpringBootApplication annotation on the main entry class enables SpringBoot capabilities such as automatic configuration, component scanning, and so on.

11. How do you understand the Starters in Spring Boot?

“Starters” is a set of “Starters” that can be integrated into your app, giving you a one-stop way to integrate Spring and other technologies without having to dig around for sample code and dependencies. If you want to use Spring JPA to access a database, simply add the spring-boot-starter-data-jPA initiator dependency.

“Starters” includes a lot of the dependencies that you’ll need for projects that will run quickly and continuously, and are a set of supported, managed transitive dependencies.

How do I run some specific code when Spring Boot starts?

You can implement interfaces ApplicationRunner or CommandLineRunner, both of which are implemented in the same way, providing only a run method

13. What are the configuration reading methods available in Spring Boot?

Spring Boot can bind variables via @propertysource,@Value,@Environment, and @ConfigurationProperties

14. What logging frameworks does Spring Boot support? What are the recommended and default logging frameworks?

Spring Boot supports Java Util Logging, Log4j2, Lockback as the Logging framework, and if you use the Starters launcher, Spring Boot will use Logback as the default Logging framework.

15. What are the ways to implement hot deployment in SpringBoot?

There are two main ways:

Spring Loaded


16, How do you understand the Spring Boot configuration load order?

In Spring Boot, you can load configurations in the following ways.

1) Properties file;

2) YAML files;

3) System environment variables;

4) Command line parameters;

And so on…

17, Spring Boot how to define multiple sets of different environment configuration?

Provides multiple sets of configuration files, such as:

The runtime specifies the specific configuration file

18. Is Spring Boot compatible with old Spring projects?

Compatible, using the @importResource annotation to import the old Spring project configuration file.

19. What are the methods to protect Spring Boot applications?

Use HTTPS in production

Check your dependencies using Snyk

Upgrade to the latest version

Enable CSRF protection

Use content security policies to prevent XSS attacks

20.What’s new with Spring Boot 2.X? What’s the difference from 1.x?

Configuration changes

JDK Version Upgrade

Upgrade the third-party class library

Responsive Spring programming support

Support HTTP / 2

Configuring property Binding

More improvements and enhancements…

Finally finished writing, I hope you study hard before going to the interview, otherwise the interviewer asked these questions, and can not answer it will be embarrassing. Understanding these issues will also help you understand Spring Boot.

These 20 interview questions are for season 1, and more Spring Boot/Cloud related interview questions will be compiled later.