前信
- SpringSecurity
1.1 SpringSecurity 概述
1.2 SpringSecurity介绍与环境搭建
1.3 SpringSecurity认证和授权
1.3.1 SpringSecurity使用前重复说明
1.3.2 SpringSecurity认证和授权代码实战
1.3.3 SpringSecurity注销和权限控制
1.3.4 SpringSecurity记住我和首页开发
前言
① 市面上关于安全比较有名的:Shiro,Spring Security !
➁ Java中对于关于安全的配置,可以使用"过滤器/拦截器"之类的,就算没有安全框架也可以实现安全的部署,但是框架用起来更加方便简单一些,相比较’拦截器/过滤器’来实现安全,其代码较复杂。
➂ 安全应该在设计之初就应该考虑进来了!
➃ Shiro,Spring Security框架 ==>这两个框架很像,仅仅是类和名称不同而已。
1. SpringSecurity
1.1 SpringSecurity 概述
② 一般来说,Web 应用的安全性包括两个部分:
- 用户认证(Authentication)
- 用户授权(Authorization)
⑴ 用户认证:用户能否访问某系统,系统通过校验用户名和密码来完成
认证过程。
⑵ 用户授权:用户是否有权限执行某个操作。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。
- 一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一
系列的权限。
----------------------------------------------
③ Spring Security 框架对于"用户认证和授权"都有很好的支持。
⑴ 在用户认证方面,Spring Security 框架支持主流的认证方式,
包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID 和 LDAP 等。
⑵ 在用户授权方面,Spring Security 提供了基于角色的访问控制和访
问控制列表(Access Control List,ACL),可以对应用中的领域对象进
行细粒度的控制。
1.2 SpringSecurity 介绍与环境搭建
① 权限一般分为以下几种:
⑴ 第一种"功能权限":就是每个人拥有哪些功能
- 如果你是管理员:你就可以进入后台,
- 如果你是个普通用户:你就无法进入后台,
- 如果你是个游客:你就只能看网页。
- 如果你是个博主:你就拥有边编辑和修改网页的功能
⑵ 第二种"访问权限":就是有些页面有的人可以访问,有的人访问不
了。
⑶ 第三种"菜单权限":相同的后台页面。
------------------------------------------------
③ 演示:创建SpringBoot项目并搭建SpringSecurity环境
⑴ 第一步:pom.xml引入thymeleaf模板引擎依赖,及Web依赖
<!--Web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--thymeleaf依赖-->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>
⑵ 第二步:导入需要用到的静态资源
- css+js等资源 :放置在resources包下的static包下。
- index.html/login.html等页面资源:放置在resources包下的templates包下。
⑶ 第三步:.properties配置文件-->配置关闭thymeleaf模板引擎的缓存,方便随时调试
# 关闭thymeleaf模板引擎的缓存,方便随时调试
spring.thymeleaf.cache=false
⑷ 第四步:做完上面准备工作,我们去测试一下导入的静态资源页面!
- 创建一个controller实现各个页面跳转访问测试(类似于专门跳路由的!)
/**
* 1.这个controller作用:
* -->用来专门跳转到各个页面的controller
*
* 2. 我们要让各个页面都可以访问得到
*/
@Controller
public class RouterController {
/**
* 一:首先可以进首页index.html
*/
@RequestMapping({"/","/index"})
public String index() {
return "index";
}
/**
* 二:其次可以跳转到登录页login.html
*/
@RequestMapping("/toLogin")
public String toLogin() {
return "views/login";
}
/**
* 三:以及1.html/2.html/3.html -->这些权限的页面
*
* -->views包下涉及了"level1/2/3",总共9个页面(一个level/下面分别有三个页面)
* -->打算利用三个controller接口访问方法,来实现
*
*/
@RequestMapping("/level1/{id}")
public String level1(@PathVariable("id") int id) {
return "views/level1/" + id;
}
@RequestMapping("/level2/{id}")
public String level2(@PathVariable("id") int id) {
return "views/level2/" + id;
}
@RequestMapping("/level3/{id}")
public String level3(@PathVariable("id") int id) {
return "views/level3/" + id;
}
}
⑸ 第五步:网页访问测试跳转页面效果
http://localhost:8080/index
-----------------------------------------------------
④ 对于上面环境搭建就完成了,接下去我们要实现的是:
⑴ 针对于权限,有些人进来他可以访问level1,但是level2/level3
是访问不了的!
⑵ 以及用户登录之后进入首页,不同的用户所看到的东西是不相同的!
⑶ 甚至对于登录到首页的用户,有些东西不应该对所有人展示出来。
⑤ 因此接下去要利用AOP的思想(横切进去),来实现SpringSecurity开发。
-->AOP横切思想,不修改原来代码就可以加很多拦截的操作功能进去。
1.3 SpringSecurity 认证和授权
1.3.1 SpringSecurity 使用前重复说明
① Spring Security 是针对Spring项目的安全框架,也是Spring Boot底层
安全模块默认的技术选型。
⑴ 他可以实现强大的Web安全控制,对于安全控制。
⑵ 我们仅需要引入spring-boot-starter-security 模块,
进行少量的配置,即可实现强大的安全管理!
------------------------------------------------------
② Spring Security记住几个类:
⑴ WebSecurityConfigurerAdapter:
------>自定义Security策略(需去继承此类)
⑵ AuthenticationManagerBuilder:
------>自定义认证策略
⑶ @EnableWebSecurity:
------>开启WebSecurity模式
---------------------------------------------------------
③ Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)。
⑴ “认证”(Authentication)
- 身份验证是关于验证用户的凭据,通过用户名和密码来验证身份。
- 身份验证通常通过用户名和密码完成,有时与身份验证因素结合使用。
⑵ “授权” (Authorization)
- 授权发生在系统成功验证您的身份后,最终会授予您访问资源
(如信息,文件,数据库,资金,位置,几乎任何内容)的完全权限。
- 这个概念是通用的,而不是只在Spring Security 中存在。
1.3.2 SpringSecurity 认证和授权代码实战
① SpringSecurity安全开发步骤演示
## 以下的开发实现上面"1.2 SpringSecurity介绍及环境搭建"环境基
础来做的。
-----------------------------------------------------
⑴ 第一步:pom.xml导入Security依赖
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
⑵ 第二步:配置controller请求访问的跳转
/**
* 1.这个controller作用:
* -->用来专门跳转到各个页面的controller
*
* 2. 我们要让各个页面都可以访问得到
*/
@Controller
public class RouterController {
/**
* 一:首先可以进首页index.html
*/
@RequestMapping({"/","/index"})
public String index() {
return "index";
}
/**
* 二:其次可以跳转到登录页login.html
*/
@RequestMapping("/toLogin")
public String toLogin() {
return "views/login";
}
/**
* 三:以及1.hrml/2.html/3.html -->这些权限的页面
*
* -->views包下涉及了"level1/2/3",总共9个页面(每个level/有三个页面)
* -->打算利用三个controller接口访问方法,来实现
*
*/
@RequestMapping("/level1/{id}")
public String level1(@PathVariable("id") int id) {
return "views/level1/" + id;
}
@RequestMapping("/level2/{id}")
public String level2(@PathVariable("id") int id) {
return "views/level2/" + id;
}
@RequestMapping("/level3/{id}")
public String level3(@PathVariable("id") int id) {
return "views/level3/" + id;
}
}
⑶ 第三步:如何配置Security呢?来进行简单上手测试一下
- 创建一个config包-->下面创建一个SecurityConfig类来进行安全配
置,测试Security安全。
- 对于Security的配置可以尝试着跟着官方文档的例子,一步步跟着配
置:
--> https://docs.spring.io/spring-security/site/docs/5.2.0.RELEASE/reference/
htmlsingle/#hello-web-security-java-configuration
SecurityConfig配置类,完整代码如下:
/**
* 自定义权限规则
*/
@EnableWebSecurity // 开启WebSecurity模式
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 1. 下面对于权限的配置:属于链式编程
*
* -->下面是定制请求的授权规则
* -->下面的配置就是AOP横切的思想(不改变原有代码,就能实现其他操作)
* 1.1 下面的configure()方法,就实现了第一个功能:根据权限实现认证(用户授权)
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
/**
* 实现:首页所有人可以访问,功能页只有对应有权限的人才能访问
*/
// 定制请求的授权规则
// 首页所有人可以访问
http.authorizeRequests().antMatchers("/").permitAll()
//包level1下的所有页面,只有vip1这个角色才可以访问
.antMatchers("/level1/**").hasRole("vip1")
//包level2下的所有页面,只有vip2这个角色才可以访问
.antMatchers("/level2/**").hasRole("vip2")
//包level3下的所有页面,只有vip3这个角色才可以访问
.antMatchers("/level3/**").hasRole("vip3");
/**
* 1. http.formLogin():表示开启自动配置的登录功能
* 1.1 login 请求来到登录页
* 1.2 login?error 重定向到这里表示登录失败
*
* ↓↓ 下面表示如果没有权限,自动跳转到登录页
*/
http.formLogin();
}
/**
* 2. 下面的configure()方法,实现第二个功能:用户认证
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
/**
* //在内存中定义,也可以在jdbc中去拿....(正常应该从数据库中读)
* //Spring security 5.0中新增了多种加密方式,也改变了密码的格式。
* //要想我们的项目还能够正常登陆,需要修改一下configure中的代码。我们要将前端传过来的密码进行某种方式加密
* //spring security 官方推荐的是使用bcrypt加密方式。
*/
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
// 表示给某一个用户,赋予一个密码并设置密码的编码加密格式才能实现登录,以及赋予用户角色
.withUser("test").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
.and()
.withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1",
.withU"vip2","vip3")
.and()ser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2");
}
}
⑷ 第四步:测试上面代码:
- 网页访问:localhost:8080/index 当我们登录"test"用户,点击
level2/level3/ 可以访问,但是点击/level1访问不了!
- 此时就实现了每个用户只能访问自定义的规则网页。
(不同角色有访问不同网页的权限,我们将此角色赋给用户,
该用户就拥有了访问对应网页的权限了!)
- 用户的认证和权限配置成功!
1.3.3 SpringSecurity 注销和权限控制
① 在"1.3.2 SpringSecurity认证和授权代码实现"代码基础上
实现注销和权限控制。
---------------------------------------------------
⑴ "注销"的需求:
---> 开启注销功能,登录成功后点击注销,发现注销完毕会跳转到登录
页面!
⑵ "权限控制"的需求:
---> 用户没有登录的时候,导航栏上只显示登录按钮,
用户登录之后,导航栏可以显示登录的用户信息及注销按钮!
还有就是,比如test这个用户,它只有 vip2,vip3功能,
那么登录则只显示这两个功能,而vip1的功能菜单不显示!
---------------------------------------------------------------
② Security注销和权限控制代码演示步骤如下:
⑴ 第一步:实现注销功能并自动跳转到登录页面
- 只需要在SecurityConfig类中,增加一行以下代码即可!
@Override
protected void configure(HttpSecurity http) throws Exception {
//开启注销功能,若用户登录成功后点击注销-->自动跳转到首页
http.logout().logoutSuccessUrl("/");
}
- 前端页面增加"注销"的按钮的配置。
⑵ 第二步:权限控制-用户登录显示自己只能看到的信息,其他信息屏蔽
---> 这里需要结合thymeleaf。修改前端页面,根据权限判断显示
根据不同用户显示不同页面的信息。(这里属于前端配置:thymeleaf和
Security的结合)
--->前端页面的一些配置thymeleaf配置完后,无法登陆,需要
springboot需要降低版本才可以才可以实现效果
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
-->此时将SpringBoot的版本降到:2.0.9 之后去登录就实现了,根据登录获取登录用户名。
-2 后端:在SecurityConfig类增加一行代码:
@Override
protected void configure(HttpSecurity http) throws Exception {
/**
* 1. //关闭csrf功能:跨站请求伪造,默认只能通过post方式提交logout请求
* 1.1 登录失败可能存在的原因csrf
*/
http.csrf().disable();
}
-3 前端配置根据不同的用户角色,显示不同的页面信息(属于前端配
置)。
⑶ 第三步:测试登录localhost:8080/login -->
- 输入三个用户(linzk,root,guest),查看是否显示不同的页面。
1.3.4 SpringSecurity记住我和首页开发
① 在网站中设置"记住我"功能:我们只要登录之后,关闭浏览器,再登
录,就会让我们重新登录,但是很多网站的情况,就是有一个记住密码的
功能。
② 定制使用我们自己写的Login界面。
③ 记住我及定制首页代码演示步骤如下:
⑴ 第一步:SecurityConfig类中增加一行配置↓:
@Override
protected void configure(HttpSecurity http) throws Exception {
/**
* 1. 开启记住我功能 cookie 默认保存两周
*/
http.rememberMe();
}
-->即可实现“用户登录一次”,下次可以将保持两周,也可以手动删网页
的cookie重新登录。
⑵ 第二步:定制登录跳转到我们自己的登录页面,不使用默认的
-1 SecurityConfig类中增加一行以下配置↓:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.formLogin().loginPage("/toLogin");
}
-->也可以使用其他方式,这里只举例这种定制跳转到指定登录页的其中
一种方式!
-2 在此基础上,增加"记住我"功能。
/**
* 1. 增加".rememberMeParameter("remember")"
* ---> 这句话表示自定义接收前端参数为remember的值
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.rememberMe().rememberMeParameter("remember");
}
⑶ 测试,访问localhost:8080/toLogin 输入不同用户测试!