用户密码加解密(数据库层面)

1、密码加密
格式:ENCODER.encode(密码明文)
说明:加密后作为密码密文保存到数据库

例如:ENCODER.encode("123456") //$2a$10$PVUHriO67YxRYq84eXVpjefGMmgiScUIHRCaDpj0eWti/535fV83e

2、密码验证

PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
passwordEncoder.encode("123456") //返回结果:{bcrypt}$2a$10$hgaJ98H2ntO.DE2pE.fWZuHG29zJn7ksr8gBsiW1XIX.bhEYXeK1.
passwordEncoder.matches("123456", passwordEncoder.encode("123456"))
passwordEncoder.matches("123456", "{bcrypt}" + ENCODER.encode("123456"))

3、案例
3.1、密码初始化

{tajia-upms-biz}SysUserServiceImpl.java
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean saveUser(UserDTO userDto) {
    SysUser sysUser = new SysUser();
    BeanUtils.copyProperties(userDto, sysUser);
    sysUser.setDelFlag(CommonConstants.STATUS_NORMAL);
    sysUser.setPassword(ENCODER.encode(userDto.getPassword()));
    baseMapper.insert(sysUser);
    List<SysUserRole> userRoleList = userDto.getRole().stream().map(roleId -> {
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(sysUser.getUserId());
        userRole.setRoleId(roleId);
        return userRole;
    }).collect(Collectors.toList());
    return sysUserRoleService.saveBatch(userRoleList);
}

 

3.2、构建userdetails

{tajia-common-security}SysUserServiceImpl.java

/**
 * 构建userdetails
 *
 * @param result 用户信息
 * @return
 */
private UserDetails getUserDetails(R<UserInfo> result) {
    if (result == null || result.getData() == null) {
        throw new UsernameNotFoundException("用户不存在");
    }

    UserInfo info = result.getData();
    Set<String> dbAuthsSet = new HashSet<>();
    if (ArrayUtil.isNotEmpty(info.getRoles())) {
        // 获取角色
        Arrays.stream(info.getRoles()).forEach(roleId -> dbAuthsSet.add(SecurityConstants.ROLE + roleId));
        // 获取资源
        dbAuthsSet.addAll(Arrays.asList(info.getPermissions()));

    }
    Collection<? extends GrantedAuthority> authorities = AuthorityUtils
            .createAuthorityList(dbAuthsSet.toArray(new String[0]));
    SysUser user = info.getSysUser();
    boolean enabled = StrUtil.equals(user.getLockFlag(), CommonConstants.STATUS_NORMAL);
    // 构造security用户
    // user.getPassword() 就是数据库密码
    return new TajiaUser(UserTypeEnum.ADMIN_USER.getUserType(), user.getUserId(), user.getDeptId(), user.getPhone(), user.getAvatar(), user.getTenantId(),
            user.getUsername(), SecurityConstants.BCRYPT + user.getPassword(), enabled, true, true,
            !CommonConstants.STATUS_LOCK.equals(user.getLockFlag()), authorities);
}

 

3.3、登录密码验证
在{tajia-common-security}XkUserAuthenticationProvider,继承AbstractUserDetailsAuthenticationProvider,用来登录验证。

SpringSecurity登录验证详细文档 

@Override
protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
    if (authentication.getCredentials() == null) {
        log.debug("Failed to authenticate since no credentials provided");
        throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
    } else {
        //密码明文
        String presentedPassword = authentication.getCredentials().toString();
        //验证登录密码是否匹配
        if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
            this.logger.debug("Failed to authenticate since password does not match stored value");
            throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
        }
    }
}

注意:手动修改数据库密码,要清理缓存。

posted on 2021-10-30 17:22  Ruthless  阅读(1902)  评论(0编辑  收藏  举报