1、SpringSecurity框架简介
1.1 摘要
Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。
主要包括2部分:认证(Authentication)和授权(Authorization)
认证:系统认为用户能否登录
授权:系统判断用户能否有权限去做什么事情
1.2 历史
1.3 同款产品对比
1.3.1 SpringSecurity
- 和Spring无缝整合
- 全面的权限控制
- 专门为web开发而设计
- 重量级
1.3.2 Shiro
- 轻量级
- 通用性(好处:不局限于web环境,缺陷:在web环境中需要自己编写代码定制)
2、Hello Spring Security
创建一个maven项目
pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ycm</groupId>
<artifactId>spring-security-test</artifactId>
<version>1.0-SNAPSHOT</version>
<!--父依赖-->
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.2.1.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
创建Springboot启动方法
创建一个测试用的controller
点击运行
在浏览器地址栏输入localhost:8080/hello
此时就进入SpringSecurity的拦截页面,需要认证通过以后才可以进行访问
默认的用户名:user,密码是控制台打印出来的一个随机字符串
输入账号和密码就可以成功访问了
3、修改SpringBoot默认的用户名和密码
(1)通过配置文件修改
(2)通过配置类
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); //密码解析器
String encodePwd = passwordEncoder.encode("123456"); //必须转成对应的密码格式才可以
auth.inMemoryAuthentication().withUser("root").password(encodePwd).roles("admin");
}
@Bean
public PasswordEncoder passwordEncoder(){
//注入密码解析器
return new BCryptPasswordEncoder();
}
}
4、通过查询数据库完成用户认证
数据库表创建,创建一个users表,其中的表结构如下
新加入pom文件依赖:
<!--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>
配置文件添加配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/security?serverTimezone=GMT%2B8
username: root
password: root
创建Users对应实体类
@Data
public class Users {
@TableId(type = IdType.AUTO)
private Integer id;
private String username;
private String password;
}
整合MBatisPlus
@Mapper
@Repository
public interface UsersMapper extends BaseMapper<Users> {
}
编写配置类
@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService; //用于实现用户登录功能的接口,先注入容器,然后新建一个类实现它
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder(){
//注入密码解析器
return new BCryptPasswordEncoder();
}
}
登录逻辑接口
@Service("userDetailsService")
public class LoginService implements UserDetailsService {
@Autowired
private UsersMapper usersMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//通过username从数据库查询
QueryWrapper<Users> wrapper = new QueryWrapper<>();
wrapper.eq("username", username);
Users users = usersMapper.selectOne(wrapper);
if (users == null) {
throw new UsernameNotFoundException("用户名不存在");
}
//密码加密
String pwd = new BCryptPasswordEncoder().encode(users.getPassword());
List<GrantedAuthority> auths = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
return new User(users.getUsername(),pwd, auths);
}
}