上一篇中[Spring Cloud] - Spring Security实践(三)- 数据库方式的基本认证和授权,提到了使用spring security默认的数据库模型进行认证和鉴权,其使用框架定义的表结构,并且初始用户信息依然在代码中设置,显然这并不能用于实际项目的设计与开发,首先,数据库表结构应该符合项目需求的结构,其次,用户信息不可能以硬编码的形式保存于java代码中。所以,我们需要继续探究security框架,并实现自定义的获取用户的方式。

此方式分为以下几个部分:

  1. 实现UserDetails接口的用户信息实体类
  2. 数据库查询的框架或方式 - mybatis/jpa/hibernate等等均可
  3. (重要)实现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两个用户进行登录认证。


yizheng
301 声望27 粉丝

一蓑烟雨任平生


引用和评论

0 条评论