SpringBoot + SpringSecurity + MybatisPlus完成查询数据库完成用户认证
文章目录
一、概览
SpringSecurity两大核心功能:认证(判断用户能否满足登录条件)、授权(判断登录用户是否有权利做某些事情)
特点:
- 与spring整合方便
- 全面的权限控制 为Web开发而设计
- 新版本对整个框架进行了分层抽取分为核心模块和Web模块,单独引入核心模块可以脱离Web环境
- 重量级
对比Shiro:
- 轻量级
- 不局限于 Web 环境,可以脱离 Web 环境使用
- 在 Web 环境下一些特定的需求需要手动编写代码定制
二、入门案例
1.默认配置进行注册登录(默认密码)
1.1 引入依赖后(启动项目会自动进行相关配置)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
1.2 编写controller层
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/hello")
public String hello(){
return "hello springsecurity";
}
}
1.3 1启动项目控制台获取密码,账号默认root进行登录,只要登录成功之后,之后的访问其他网址不再需要重新登录。
2.修改账号密码的三种方式
2.1 方式一:配置文件方式
#spring.security.user.name=pmh
#spring.security.user.password=pmh
2.2 方式二:配置类方式:继承WebSecurityConfigurerAdapter,重写configure方法,在方法里面利用auth参数进行账号、密码、角色的设置;这边密码需要进行加密处理;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode = bCryptPasswordEncoder.encode("zyf");
auth.inMemoryAuthentication().withUser("zyf").password(encode).roles("admin");
}
@Bean //没有这个PasswordEncoder会报错null
PasswordEncoder get(){
return new BCryptPasswordEncoder();
}
}
三、SpringBoot + SpringSecurity + MybatisPlus完成查询数据库完成用户认证(完整过程)
1.引入依赖
<dependencies>
<!--web场景启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot测试场景-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--springsecurity-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<!--没加版本号依赖没法引入-->
<version>3.0.5</version>
</dependency>
<!--mysql这边需要配置数据源-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok 用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
2. 创建数据库以及对应的实体类
CREATE DATABASE demo;
USE demo;
CREATE TABLE users(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) UNIQUE NOT NULL,
PASSWORD VARCHAR(100)
);
-- 密码 atguigu
INSERT INTO users VALUES(3,'pmh','pmh');
CREATE TABLE role(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
INSERT INTO role VALUES(1,'管理员');
INSERT INTO role VALUES(2,'普通用户');
CREATE TABLE role_user(
uid BIGINT,
rid BIGINT
);
INSERT INTO role_user VALUES(1,1);
INSERT INTO role_user VALUES(2,2);
CREATE TABLE menu(
id BIGINT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
url VARCHAR(100),
parentid BIGINT,
permission VARCHAR(20)
);
INSERT INTO menu VALUES(1,'系统管理','',0,'menu:system');
INSERT INTO menu VALUES(2,'用户管理','',0,'menu:user');
CREATE TABLE role_menu(
MID BIGINT,
rid BIGINT
);
INSERT INTO role_menu VALUES(1,1);
INSERT INTO role_menu VALUES(2,1);
INSERT INTO role_menu VALUES(2,2);
@Data //这边可能存在注解不生效的问题,原因:没有安装插件 解决方法https://blog.csdn.net/qq_41097820/article/details/88839130
public class Users {
private Integer id;
private String username;
private String password;
}
3. 连接数据库
#连接数据库
###mysql 连接信息,test是数据库名 springboot2.2开始使用mysql8,需要添加时区东八区
spring.datasource.url=jdbc:mysql://ip地址:3306/demo?serverTimezone=GMT%2B8
###用户名
spring.datasource.username=root
###密码
spring.datasource.password=Aa!123456
###驱动 mysql8驱动需要加cj
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
4. 整合MyBatisPlus
4.1 编写接口继承BaseMappr<泛型> 泛型指明对哪个实体类进行操作
//编写接口继承BaseMappr<泛型> 泛型指明对哪个实体类进行操作
@Repository
public interface UsersMapper extends BaseMapper<Users> {
}
4.2 添加包扫描注解
@SpringBootApplication
@MapperScan("com.example.securitylogin.mapper")
public class SecurityLoginApplication {
public static void main(String[] args) {
SpringApplication.run(SecurityLoginApplication.class, args);
}
}
5. 第三种修改账号密码的方式实现UserDetailsService
5.1 编写配置类继承WebSecurityConfigurerAdapter,注入我们新实现的userDetailsService,重写configure方法
@Configuration
public class SecurityConfig1 extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(get());
}
@Bean
PasswordEncoder get(){
return new BCryptPasswordEncoder();
}
}
5.2 实现UserDetailsService,定义我们自己的查询数据库方式,返回UserDetails对象
@Service("userDetailsService")
public class MyUserDeatilsService implements UserDetailsService {
@Autowired
private UsersMapper usersMapper; //引入依赖,实现了接口,可以利用实现类操作数据库
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//角色这边先采用任意的
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList("role");
// 这边我们需要根据用户名从数据库中获取user实例
// 首先利用QueryWrapper来构造查询条件
QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
// 利用写好的实现类查询返回数据
Users users = usersMapper.selectOne(queryWrapper);
// 判断
if(users == null){
throw new UsernameNotFoundException("用户名不存在");
}
return new User(users.getUsername(),new BCryptPasswordEncoder().encode(users.getPassword()), authorities);
}
}