An article takes you to get Spring Security to store user data in the database

一、UserDetailService

Spring Security supports a variety of different data sources, these different data sources will eventually be packaged into UserDetailsServicean instance in micro personnel (https://github.com/lenve/vhr) project, we create a class of their own implement UserDetailsServicethe interface, in addition to their package, we can also use the system provided by default UserDetailsServiceinstances, such as the articles and introduce InMemoryUserDetailsManager.

We look at UserDetailsServicewhat classes have achieved:

Insert picture description here
It can be seen in several implementation classes can be used directly, in addition InMemoryUserDetailsManager, there are a JdbcUserDetailsManageruse JdbcUserDetailsManagerallows us a way through JDBC to connect the database and Spring Security.

Need to add jdbc and mysql dependencies here:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
</dependency>     

二 、 JdbcUserDetailsManager

JdbcUserDetailsManager itself provides a database model, which is stored in the following location:

org/springframework/security/core/userdetails/jdbc/users.ddl

The contents of the script stored here are as follows:

create table users(username varchar_ignorecase(50) not null primary key,password varchar_ignorecase(500) not null,enabled boolean not null);
create table authorities (username varchar_ignorecase(50) not null,authority varchar_ignorecase(50) not null,constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);

You can see, the script has a data type varchar_ignorecase, this is actually created for HSQLDB database, and we use MySQL does not support this type of data, so here we need to manually adjust the data type, will varchar_ignorecasebe changed to varchar.

create table users(username varchar(50) not null primary key,password varchar(500) not null,enabled boolean not null);
create table authorities (username varchar(50) not null,authority varchar(50) not null,constraint fk_authorities_users foreign key(username) references users(username));
create unique index ix_auth_username on authorities (username,authority);

After the modification is completed, create a database and execute the script after completion.

Insert picture description here
After executing the SQL script, we can see that a total of two tables have been created: users and authorities.

The users table saves basic user information, including user name, user password, and whether the account is available.
The roles of the user are stored in the authorities.
Authorities and users are related by username.

Once configured, the next, we will be the last article by InMemoryUserDetailsManagerusing data provided by the user JdbcUserDetailsManagerinstead of out, as follows:

	@Autowired
    DataSource dataSource;

    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
    
    
        JdbcUserDetailsManager manager = new JdbcUserDetailsManager();
        manager.setDataSource(dataSource);
        if (!manager.userExists("yolo")) {
    
    
            manager.createUser(User.withUsername("yolo").password("123").roles("admin").build());
        }
        if (!manager.userExists("nlcs")) {
    
    
            manager.createUser(User.withUsername("nlcs").password("123").roles("user").build());
        }
        return manager;
    }

The meaning of this configuration is as follows:

(1) Construction of a first JdbcUserDetailsManagerexample.
(2) to JdbcUserDetailsManageradd a DataSource object instance.
(3) calls the userExistsmethod to determine if the user exists, if does not exist, create a new user out (this code will be executed because every time the project started, so add a judge, to avoid duplication of creating a user).
Create a method (4) user and before we InMemoryUserDetailsManagerare basically the same creation method.

Here createUseror userExistsmethod calls are actually written SQL to judge, we can see coming out from its source (part):

public class JdbcUserDetailsManager extends JdbcDaoImpl implements UserDetailsManager,
  GroupManager {
    
    
 public static final String DEF_USER_EXISTS_SQL = "select username from users where username = ?";

 private String userExistsSql = DEF_USER_EXISTS_SQL;

 public boolean userExists(String username) {
    
    
  List<String> users = getJdbcTemplate().queryForList(userExistsSql,
    new String[] {
    
     username }, String.class);

  if (users.size() > 1) {
    
    
   throw new IncorrectResultSizeDataAccessException(
     "More than one user found with name '" + username + "'", 1);
  }

  return users.size() == 1;
 }
}

From this source code can be seen, userExistsperform logical method is actually a call JdbcTemplateto perform a pre-defined SQL scripts, and then determine whether the user exists, the other judgment methods are similar, I will not repeat them.

Three, database support

Through the previous code, everyone sees that database support is needed here, so we add the following two dependencies to the project:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

Then configure the database connection in application.properties:

spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/security?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

Because Mysql 8 is selected here, the configuration information needs to be added:serverTimezone=Asia/Shanghai

After the configuration is complete, you can start the project.

After the project is started successfully, we can see that two users are automatically added to the database, and the users are configured with roles. As shown below:

Insert picture description here

Insert picture description here

Four, test login

Then we can test.

Insert picture description here
Insert picture description here
During the testing process, if the user in the database enabledset properties for false, disable the account, then re-login failures will use the account to log on.

Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/nanhuaibeian/article/details/108602260