Spring Security 笔记(4)——持久化

在前面的章节中,我使用的用户信息都是基于代码配置、信息存于内存,在实际项目中,用户认证和角色信息肯定是持久化的,需通过连接数据库存取。

修改

之前我使用基于内存的 InMemoryUserDetailsManager,对于从数据库存取 Spring Security 关系,需要使用 JdbcUserDetailsManager,其提供了 users.ddl

1
2
3
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);

要使用 JdbcUserDetailsManager,需手动执行建表语句:

1
2
3
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);

添加 JDBC 依赖:

1
2
3
4
5
6
7
8
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

添加 datasource 配置:

1
2
3
spring.datasource.username=root
spring.datasource.password=bolitao
spring.datasource.url=jdbc:mysql://192.168.79.131:3306/spring_security_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai

修改密码加密方式:

1
2
3
4
5
@Bean
PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
    //        return NoOpPasswordEncoder.getInstance();
}

修改 UserDetailsService:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@Autowired
DataSource dataSource;

@Override
@Bean
protected UserDetailsService userDetailsService() {
    JdbcUserDetailsManager userDetailsManager = new JdbcUserDetailsManager(dataSource);
    if (!userDetailsManager.userExists("bolitao")) {
        userDetailsManager.createUser(
            User.withUsername("bolitao").password(passwordEncoder().encode("bolitao")).roles("ADMIN").build());
    }
    if (!userDetailsManager.userExists("test1")) {
        userDetailsManager.createUser(
            User.withUsername("test1").password(passwordEncoder().encode("test")).roles("USER").build());
    }
    return userDetailsManager;
}

测试:

修改代码后启动项目,可发现 authorities 和 users 表多了数据:

测试

登录:

将数据库 username 为 bolitao 的记录修改,enabled 设置为 0,注销后进行登录,可发现提示账户被禁用:

加载评论