1、相关依赖
这里不做代码演示,本案例使用的是mybatis-plus框架操作数据库
2、实体类
创建一个实体类,建议尽量别用
User
作为实体类的类名,和org.springframework.security.core.userdetails.User
冲突,容易导错包,但本例中使用User
做为实体类,给想用User的小伙伴做个演示。(使用这种方式导包时,导入的都是自定义实体类User
包,只有在最后将数据保存到org.springframework.security.core.userdetails.User
类中才会用到Spring内部的User
类)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String username;
private String password;
}
3、连接数据库
注意:不写时区在新版的Spring中会报错
serverTimezone
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springsecurity?serverTimezone=GMT%2B8
4、编写配置类
采用构造器注入的方式创建
UserDetailsService
对象,将PasswordEncoder
对象注入到Spring容器中
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
private UserDetailsService userDetailsService;
@Autowired
public SecurityConfig(UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
}
5、使用mybatis-plus框架查询数据库
package com.monster.security.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.monster.security.entities.User;
import org.springframework.stereotype.Repository;
/**
* @author Monster
* @version v1.0
* @time 03-25-2021 15:21:46
* @description:
*/
@Repository
public interface UserMapper extends BaseMapper<User> {
}
6、实现UserDetailsService
接口,查询数据库,将查到的User对象的用户名和密码作为参数创建org.springframework.security.core.userdetails.User
对象
package com.monster.security.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.monster.security.entities.User;
import com.monster.security.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author Monster
* @version v1.0
* @time 03-25-2021 14:39:04
* @description:
*/
@Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
private QueryWrapper<User> wrapper;
private UserMapper userMapper;
@Autowired
public MyUserDetailsService(UserMapper userMapper) {
this.userMapper = userMapper;
this.wrapper = new QueryWrapper<User>();
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 查询数据库
wrapper.eq("username", username);
User user = userMapper.selectOne(wrapper);
if(user == null) {
throw new UsernameNotFoundException("用户名不存在");
}
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("admin");
return new org.springframework.security.core.userdetails.User(user.getUsername(), new BCryptPasswordEncoder().encode(user.getPassword()), authorities);
// return new org.springframework.security.core.userdetails.User("haha", new BCryptPasswordEncoder().encode("999"), AuthorityUtils.createAuthorityList("admin"));
}
}