SpringSecurity学习系列(二)

自定义登录用户账号密码

第二章自定义登录账号密码


@TOC

前言

自定义SpringSecurity的登录账号与密码
项目使用的框架是: SpringBoot + MyBatis-Plus + SpringSecurity

一、实现步骤

1.通过配置文件实现

#这是yml配置文件形式
#properties则是 spring.security.user.name: 这种形式
spring:
  security:
    user:
      name: #自定义用户名
      password: #自定义密码

2.通过配置类实现

创建一个类,通过@Configuration注解标明是一个配置类
同时继承 WebSecurityConfigureAdapter

/**
 * 通过配置类实现自定义用户名
 * @author xiao-_-wu
 * @date 2021/4/8 15:03
 */
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        // 在给定密码的时候需要先把密码进行encode编码
        String password = passwordEncoder.encode("123");
        auth.inMemoryAuthentication()
                .withUser("wu-_-jia")
                .password(password)
                // 这里是给定用户操作权限
                .roles("admin");
    }

	/**
	 * 同时,此处也创建一个方法来实例化一个 encoder
	 * 不然会报错,报错会明确提示需要这个方法
	 */
    @Bean
    PasswordEncoder getPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

3.通过实现类实现(实际开发中使用)

前置

CREATE TABLE `test_user` (
  `id` bigint NOT NULL COMMENT '主键',
  `account` varchar(40) NOT NULL COMMENT '账户',
  `nickname` varchar(40) NOT NULL COMMENT '昵称',
  `password` varchar(255) NOT NULL COMMENT '密码',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `account_status` int NOT NULL COMMENT '账户状态 0正常 1冻结',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

1.创建配置类

/**
 * 创建配置类
 * @author xiao-_-wu
 * @date 2021/4/8 15:30
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	/**
	 * 注入 UserDetailService 接口类
	 */
    @Resource
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService)
                .passwordEncoder(getPasswordEncoder());
    }

    @Bean
    PasswordEncoder getPasswordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

2.创建 UserDetailsService 的具体实现类

/**
 * @author xiao-_-wu
 * @date 2021/4/8 15:37
 */
@Slf4j
@Service("userDetailsService")
public class MyUserDetailsServiceImpl implements UserDetailsService {
	/**
	 * 这里是自己定义的用户接口
	 */
    @Resource
    private ITestUserService userService;

    @Override
    public UserDetails loadUserByUsername(String account) throws UsernameNotFoundException {
        TestUser userEntity = loginProgram(account);
        // 对用户进行授权 具体的授权方法需自定义
        List<GrantedAuthority> grantedAuthorities = loginRole(1);
        // 这里的User对象是 Security框架自带的User对象
        return new User(userEntity.getAccount(), userEntity.getPassword(), grantedAuthorities);
    }

    /**
     * 登录角色,授权方法
     * @param role 角色
     * @return ret
     */
    private List<GrantedAuthority> loginRole(Integer role) {
        String authorityString = "";
        switch (role) {
            case CommonConst.USER_ROLE:
                authorityString = CommonEnum.USER_ROLE.getMessage();
                break;
            case CommonConst.ADMIN_ROLE:
                authorityString = CommonEnum.ADMIN_ROLE.getMessage();
                break;
            default:
                throw new UsernameNotFoundException("用户信息异常");
        }
        return AuthorityUtils.commaSeparatedStringToAuthorityList(authorityString);
    }

    /**
     * 用户登录程序,具体登录方法
     * @param account 账户
     * @return ret
     */
    private TestUser loginProgram(String account){
        TestUser userEntity = userService.lambdaQuery()
                .eq(TestUser::getAccount, account)
                .eq(TestUser::getAccountStatus, 0)
                .one();
        if (userEntity == null) {
            throw new UsernameNotFoundException("用户账号不存在,或已冻结");
        }
        userEntity.setPassword(new BCryptPasswordEncoder()
                .encode(userEntity.getPassword()));
        return userEntity;
    }
}

3.其他辅助类

/**
 * 通用常量类
 * @author xiao-_-wu
 * @date 2021/4/9 9:04
 */
public class CommonConst {

    public static final int ADMIN_ROLE = 0;
    public static final int USER_ROLE = 1;

}

/**
 * 通用枚举
 * @author xiao-_-wu
 * @date 2021/4/8 17:54
 */
public enum CommonEnum {

    /**
     * 用户角色
     */
    ADMIN_ROLE(0, "admin"),
    USER_ROLE(1, "user")
    ;

    private final int code;
    private final String message;

    CommonEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}