三、Spring Reactive Security从数据库查询用户

发布时间 2023-06-06 20:34:04作者: shigp1

要从数据库查询用户,只需要配置数据库连接。同时实现的用户要实现org.springframework.security.core.userdetails.UserDetails接口。从数据库查询用户要实现org.springframework.security.core.userdetails.ReactiveUserDetailsService接口。

 

首先建表:

create table t_user(
  id_key bigserial primary key,
  username varchar(30),
  password varchar(100),
  Account_Non_Expired bool,
  Account_Non_Locked bool,
  Credentials_Non_Expired bool,
  enabled bool
  );
  
 
 create table t_roles(
   id_key bigserial primary key,
   role_name varchar(20),
   role_desc varchar(50)
 );


create table t_user_roles(
   id_key bigserial primary key,
   user_id int8,
   role_id int8
);

数据库选用Postgresql。t_user_roles是用户和角色关联表。

 

添加依赖:

 <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.2</version>
    </dependency>


    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

 

application.properties配置数据库连接:

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=xxxx

 

启动类配置mapper扫描路径:

@MapperScan("com.example.mapper")

 

添加用户实体类:

@AllArgsConstructor
@NoArgsConstructor
@ToString
@Builder
@TableName("t_user")
public class UserEntity implements UserDetails {

    /**
     * 主键
     */
    @TableId(type = IdType.AUTO)
    private Long idKey;

    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;

    /**
     * 账户是否过期
     */
    private Boolean accountNonExpired;

    /**
     * 账户是否被锁定
     */
    private Boolean accountNonLocked;

    /**
     * 密码是否过期
     */
    private Boolean credentialsNonExpired ;

    /**
     * 是否启用
     */
    private Boolean enabled;

    @TableField(exist = false)
    private Collection<SimpleGrantedAuthority> authorities;

    public Long getIdKey() {
        return idKey;
    }

    public void setIdKey(Long idKey) {
        this.idKey = idKey;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }



    public void setAccountNonExpired(Boolean accountNonExpired) {
        this.accountNonExpired = accountNonExpired;
    }


    public void setAccountNonLocked(Boolean accountNonLocked) {
        this.accountNonLocked = accountNonLocked;
    }



    public void setCredentialsNonExpired(Boolean credentialsNonExpired) {
        this.credentialsNonExpired = credentialsNonExpired;
    }



    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public void setAuthorities(Collection<SimpleGrantedAuthority> authorities) {
        this.authorities = authorities;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername() {
        return username;
    }

    @Override
    public boolean isAccountNonExpired() {
        return accountNonExpired;
    }

    @Override
    public boolean isAccountNonLocked() {
        return accountNonLocked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return credentialsNonExpired;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }
}

添加角色类:

@ToString
public class SimpleGrantedAuthority implements GrantedAuthority {

    private String authority;

    public SimpleGrantedAuthority(String authority) {
        this.authority = authority;
    }

    @Override
    public String getAuthority() {
        return authority;
    }
}

添加角色实体类:

@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@TableName("t_roles")
public class RoleEntity {

    /**
     * 主键
     */
    @TableId(type = IdType.AUTO)
    private Long idKey;

    /**
     * 角色名
     */
    private String roleName;

    /**
     * 角色描述
     */
    private String roleDesc;
}

添加关联实体类:

@AllArgsConstructor
@NoArgsConstructor
@Data
@Builder
@TableName("t_user_roles")
public class UserRoleRelationEntity {

    /**
     * 主键
     */
    @TableId(type = IdType.AUTO)
    private Long idKey;


    private Long userId;


    private Long roleId;
}

添加mapper:

public interface RoleMapper extends BaseMapper<RoleEntity> {
}

public interface UserMapper extends BaseMapper<UserEntity> {
}

public interface UserRoleRelationMapper extends BaseMapper<UserRoleRelationEntity> {
}

 

添加密码加密器:

MyReactiveSecurityConfig.class

 @Bean
public PasswordEncoder passwordEncoder(){
    return new BCryptPasswordEncoder();
}

 

添加ReactiveUserDetailsService实现类:

@Service
@Slf4j
public class MyReactiveUserDetailsService implements ReactiveUserDetailsService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserRoleRelationMapper userRoleRelationMapper;


    @Override
    public Mono<UserDetails> findByUsername(String username) {

        log.info("用户名:{}从数据库查询用户", username);

        UserEntity userEntity = userMapper.selectOne(Wrappers.lambdaQuery(UserEntity.class)
                .eq(UserEntity::getUsername, username));

        if (userEntity == null) {
            log.info("用户名:{}从数据库未查询到用户", username);
            return Mono.empty();
        }

        List<UserRoleRelationEntity> userRoleRelationEntities = userRoleRelationMapper.selectList(Wrappers.lambdaQuery(UserRoleRelationEntity.class)
                .eq(UserRoleRelationEntity::getUserId, userEntity.getIdKey()));
        log.info("用户名:{}从数据库查询角色:{}", username,userRoleRelationEntities);
        if (!CollectionUtils.isEmpty(userRoleRelationEntities)) {
            List<RoleEntity> roleEntities = roleMapper.selectList(Wrappers.lambdaQuery(RoleEntity.class)
                    .in(RoleEntity::getIdKey, userRoleRelationEntities.stream().map(UserRoleRelationEntity::getRoleId).collect(Collectors.toList())));


            List<SimpleGrantedAuthority> roles = roleEntities.stream().map(RoleEntity::getRoleName).map(SimpleGrantedAuthority::new).collect(Collectors.toList());
            userEntity.setAuthorities(roles);

            log.info("用户名:{}从数据库查询到用户:{}", username,userEntity);
        }
        return Mono.just(userEntity);
    }
}

 

添加新增用户测试:

@Autowired
private UserMapper userMapper;

@Autowired
private RoleMapper roleMapper;
@Autowired
private UserRoleRelationMapper userRoleRelationMapper;

@Autowired
private PasswordEncoder passwordEncoder;


@Test
public void test() {
    addUser("USER","普通用户", "user","123");

    addUser("ADMIN","管理员","admin","123");
}


private void addUser(String roleName,String roleDesc,String username,String password) {
    RoleEntity role = RoleEntity.builder()
            .roleDesc(roleDesc)
            .roleName(roleName)
            .build();

    roleMapper.insert(role);

    UserEntity user = UserEntity.builder().username(username)
            .password(passwordEncoder.encode(password))
            .accountNonExpired(true)
            .accountNonLocked(true)
            .enabled(true)
            .credentialsNonExpired(true)
            .build();

    userMapper.insert(user);

    UserRoleRelationEntity entity = UserRoleRelationEntity.builder()
            .userId(user.getIdKey())
            .roleId(role.getIdKey())
            .build();

    userRoleRelationMapper.insert(entity);

}