在前面的章节中,我使用的用户信息都是基于代码配置、信息存于内存,在实际项目中,用户认证和角色信息肯定是持久化的,需通过连接数据库存取。
修改
之前我使用基于内存的 InMemoryUserDetailsManager
,对于从数据库存取 Spring Security 关系,需要使用 JdbcUserDetailsManager
,其提供了 users.ddl
:
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
,需手动执行建表语句:
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 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
添加 datasource 配置:
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
修改密码加密方式:
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
// return NoOpPasswordEncoder.getInstance();
}
修改 UserDetailsService:
@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
,注销后进行登录,可发现提示账户被禁用: