上一篇中[Spring Cloud] - Spring Security实践(三)- 数据库方式的基本认证和授权,提到了使用spring security默认的数据库模型进行认证和鉴权,其使用框架定义的表结构,并且初始用户信息依然在代码中设置,显然这并不能用于实际项目的设计与开发,首先,数据库表结构应该符合项目需求的结构,其次,用户信息不可能以硬编码的形式保存于java代码中。所以,我们需要继续探究security框架,并实现自定义的获取用户的方式。
此方式分为以下几个部分:
- 实现
UserDetails
接口的用户信息实体类 - 数据库查询的框架或方式 - mybatis/jpa/hibernate等等均可
- (重要)实现
UserDetailsService
接口的service,其中需包含loadUserByUsername
方法。
1, 实体类
实体类需要实现UserDetails接口,因为service方法的返回值是这个类型。
@Data
public class User implements UserDetails {
private Long id;
private String username;
private String password;
private String roles;
private boolean enable;
private List<GrantedAuthority> authorities;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return this.enable;
}
}
2, 准备数据库
-- spring security user and authority table creation
create table users (
id bigint(20) not null auto_increment,
username varchar(50) not null,
password varchar(500) not null,
enable tinyint(4) not null default 1 COMMENT '用户是否可用',
roles text character set utf8 comment '用户角色,多个角色用逗号隔开',
primary key (id),
key username (username)
)
INSERT INTO springdemo.users (username, password, roles) VALUES('admin', '{bcrypt}$2a$10$ZaY3jXkyjDsOt/APUzEEluCdnawwb1fK.bYFq4BtNph43uPn/lR3a', 'ROLE_ADMIN,ROLE_USER');
INSERT INTO springdemo.users (id, username, password, enable, roles) VALUES('USER', '{bcrypt}$2a$10$ZaY3jXkyjDsOt/APUzEEluCdnawwb1fK.bYFq4BtNph43uPn/lR3a', 'ROLE_USER');
注:插入的密码实际为123
, 其中分为两部分,{bcrypt}表示加密方式,后面的可以通过System.out.println(new BCryptPasswordEncoder().encode("123"));
生成。
3, 数据库相关框架的引入
这里使用mybatis,具体细节不赘述。
1,创建mapper
@Component
public interface UserMapper {
@Select("SELECT * FROM users WHERE username=#{username}")
User findByUserName(@Param("username") String username);
}
2, 配置mapperScan
加到main类上即可
@MapperScan("pro.yizheng.mapper")
3,加mybatis依赖
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
4, 添加数据库配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/springdemo?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 520663
4,创建获取用户信息的service
在此之前,获取用户信息在技术上是两种方式:1,调用InMemoryUserDetailManager
, 2,调用JdbcUserDetailManager
。这两个实现类都是UserDetailService
接口的实现类。
此时实现自定义数据架构时,服务也要实现UserDetailsService
@Service
public class UserDetailService implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.findByUserName(username);
user.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRoles()));
return user;
}
private List<GrantedAuthority> generateAuthorities(String roles) {
List<GrantedAuthority> authorities = new ArrayList<>();
if (roles!=null && !"".equals(roles)){
String[] roleArray = roles.split(";");
for (String role : roleArray){
authorities.add(new SimpleGrantedAuthority(role));
}
}
return authorities;
}
}
此时,一个基本的自定义数据库的认证方式就创建好了。可以通过user/123,admin/123两个用户进行登录认证。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。