SpringSecurity入门2---基于数据库的登录

代码地址
在上文中实现了基于内存的登录,书接上文,这次我们用基于数据库的方式实现登录

使用SpringSecurity默认提供的

  1. 创建数据库即对应的表,在application.properties配置好数据源
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `enabled` tinyint(255) NOT NULL,
  PRIMARY KEY (`username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities`  (
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `authority` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  UNIQUE INDEX `ix_auth_username`(`username`, `authority`) USING BTREE,
  CONSTRAINT `fk_authorities_users` FOREIGN KEY (`username`) REFERENCES `users` (`username`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
  1. 修改WebSecurityConfig
 	@Autowired
    private DataSource dataSource;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
			auth.jdbcAuthentication().dataSource(dataSource)
			                // inMemoryAuthentication()
			                .passwordEncoder(passwordEncoder())
			                .withUser("user")
			                .password(passwordEncoder().
			                        encode("123")).roles("USER")
			                .and()
			                .withUser("admin")
			                .password(passwordEncoder().
			                        encode("123")).roles("ADMIN");
    }

重启项目,访问请求进行测试即可;在启动的过程中就会将配置的用户插入到上面创建的表中

使用自定义的登录逻辑处理

正常情况下我们系统的用户相关表是由我们自己设计,登录逻辑有我们自己的处理。我们只需要创建类重写UserDetailsServiceloadUserByUsername方法并将其注入到Spring容器中,再进行配置即可。

  1. 为了和上面的做区别,单独再创建一个users
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `id` bigint(20) NOT NULL,
  `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `enable` tinyint(4) NOT NULL DEFAULT 1,
  `roles` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;
  1. 创建对应的user实体类,需要实现UserDetails
@Data
// 表名
@TableName("users")
public class User implements UserDetails {
	// id自增长
    @TableId(type= IdType.AUTO)
    private Long id;
    private String username;
    private String password;
    private String roles;
    private boolean enable;
    // 不与数据库字段对应
    @TableField(exist = false)
    private List<GrantedAuthority> authorities; // 权限列表

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return 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;
    }
}
  1. 我使用的MybatisPlus来与数据库交互,可以根据实际情况,实现根据用户名查询到用户信息即可
  2. 创建自己的UserDetailService,重写loadUserByUsername方法,返回自己创建的User对象
@Service
public class MyUserDetailService implements UserDetailsService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username);
        // 根据用户名查询用户
        User user = userMapper.selectOne(queryWrapper);
        if(null == user){
            throw new UsernameNotFoundException("user not exist");
        }
		// Roles是String格式用逗号隔开,该工具将Role拆分成数组,并将其设置进User对象中
        user.setAuthorities(AuthorityUtils.commaSeparatedStringToAuthorityList(user.getRoles()));
        return user;
    }
}
  1. 在表中插入用户数据,注意密码需要自己手动进行加密
		BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String password = passwordEncoder.encode("123");
        System.out.println(password);

在这里插入图片描述
6. 在WebSecurityConfig中添加自己的UserDetailService

 @Autowired
    private MyUserDetailService userDetailService;
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.jdbcAuthentication().dataSource(dataSource)
//                // inMemoryAuthentication()
//                .passwordEncoder(passwordEncoder())
//                .withUser("user")
//                .password(passwordEncoder().
//                        encode("123")).roles("USER")
//                .and()
//                .withUser("admin")
//                .password(passwordEncoder().
//                        encode("123")).roles("ADMIN");
        auth.userDetailsService(userDetailService).passwordEncoder(passwordEncoder());
    }
  1. 重启项目进行测试即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值