这个学习笔记系列还在继续,Spring Security是我在写项目途中需要一个安全框架,并顺手学习下来,我由于看过这类教程看的有些迷糊,特此分享给大家,并做一个系统的梳理。
Spring Security 相对 shiro来说会有点太重了,不过技多不压身,废话不多说我们直接开始。
Spring Security安全框架是Spring全家桶中一个比较重要且功能实用的框架,能使我们快速完成权限验证以及权限认证,有兴趣了解官方教程的可以点这:Spring Security官方文档。
运行环境:JDK8
开发工具(IDE):IDEA(2020.2.3)
项目构建:Maven
相关依赖:MyBatis-Plus、SpringBoot
数据库:MySQL
前端框架:Vue2.0
项目类型:前后端分离项目
我们项目使用Maven来部署,并添加以下依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--spring security依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
里面有Spring Security依赖,可以自行复制。
为了笔记需要,我们在controller包下创建一个IndexController类并写好一个接口
/** 这是一个初始化控制器
*
*/
@Controller
public class IndexController {
@RequestMapping("/")
public String index(){
return "index";
}
@RequestMapping("/main")
@ResponseBody
public String msg(){
return "这是Marinda_Speed的文章";
}
}
当Spring Security成功依赖后,启动项目输入默认地址都会被拦截并重定向为:http://127.0.0.1/login,并且控制台还会输出那么一段话。
控制台如下:
Using generated security password: UUID字符串
不要紧张,因为Spring Security本身拥有很多 拦截器 相信小伙伴们对于拦截器也不陌生,这里简单讲一下就是把坊问路径以及坊问资源全部进行拦截处理。
登陆后则立刻 放行
Spring Security 默认登录账户和密码
用户名: user
密码:控制台得到的那个UUID
登录完成之后我们就可以正常访问拉!
这时候就会有小伙伴问了:我可不可以自定义我的登录页面呢?、自定义账号密码登录呢?,答案是可以的,官方很贴心的封装了很多配置。
我们这里使用的是SpringBoot,那我们通过注解来进行配置
在config包下创建一个名为SecurityConfig的配置类继承WebSecurityConfigurerAdapter
并实现
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 配置验证登录-> 账户以及权限设置
*
* @param auth 身份验证
* @throws Exception 异常
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
}
/**
* 拦截器 -> 路径拦截放行或者验证
*
* @param web 网络
* @throws Exception 异常
*/
@Override
public void configure(WebSecurity web) throws Exception {
}
/**
* 拦截器 -> 授权管理
*
* @param http http
* @throws Exception 异常
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
}
}
此时我们已经有了一个Spring Security配置类了,那我们就开始自定义配置。
一般数据是从数据库里面调出来的,我们先做一个基础的Demo
package cn.marinda.resturants.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 配置验证登录-> 账户以及权限设置
*
* @param auth 身份验证
* @throws Exception 异常
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 配置用户
auth.inMemoryAuthentication().withUser("admin").password("123123").roles("main");
auth.inMemoryAuthentication().withUser("user").password("123").roles("staff");
}
/**
* 拦截器 -> 路径拦截放行或者验证
*
* @param web 网络
* @throws Exception 异常
*/
@Override
public void configure(WebSecurity web) throws Exception {
}
/**
* 拦截器 -> 授权管理
*
* @param http http
* @throws Exception 异常
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// 放行/路径不需要授权
http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/main").hasRole("main");
// 开启表单验证
http.formLogin();
}
}
我们访问:http://127.0.0.1/main
重定向到login页。
输入信息:
用户名:admin
密码:123123
There is no PasswordEncoder mapped for the id "null"
这段话什么意思呢?,我们翻译一下:没有为id“null”映射的PasswordEncoder
那我们明白了,需要配置一下PasswordEncoder,那我们在配置文件中新增
/**
* 密码编码器
*
* @return {@link PasswordEncoder}
*/
@Bean
BCryptPasswordEncoder getPwordEncoder(){
// 我们使用的是BCryptPasswordEncoder方式
return new BCryptPasswordEncoder();
}
并在Auth身份验证处修改一下密码处理
/**
* 配置验证登录-> 账户以及权限设置
*
* @param auth 身份验证
* @throws Exception 异常
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 配置用户
auth.inMemoryAuthentication().withUser("admin").password(getPwordEncoder().encode("123123")).roles("main");
auth.inMemoryAuthentication().withUser("user").password(getPwordEncoder().encode("123")).roles("staff");
}
然后我们再来看看效果。
打开http://127.0.0.1/main
重定向到http://127.0.0.1/login
在表单中输入以下信息:
用户名:admin
密码:123123
(此时这里已经做了一个密码加密,我们明文密码登录就行)
细心的小伙伴们会发现我们在账户授权里面还定义了一个
user
我们来试试用这个登录
效果如下:
登陆后发生了一个403权限异常,那我们再来解析一下为什么?
细心的小伙伴们发现了,
admin
用户有main
的权限,而user
只有staff
权限,并没有main
权限,所以被限制访问了。
今天我们讲解了一下Spring Security的基本使用方法和认识了Spring Security框架。
感谢你的观看。