前言:
在web开发,安全性的提高依赖于:拦截器。过滤器
安全属性非功能性需求
做网站,安全应该在设计之初决定好
安全的框架有:
- springsecutity
- shiro
二者较为相似,除了名字、类
核心功能:认证(authentication)、授权(access-control)
权限包括:
- 功能权限
- 访问权限
- 菜单权限
- 拦截器、过滤器(代码冗余)
一、简介SpringSecurity(spring安全框架)
spring security是针对spring项目的安全框架,也是springboot底层安全模块的默认选型, 它可以实现强大的web安全控制,对于安全控制,我们仅需引入spring-boot-starter-security模块,
进行少量的配置,即可实现强大的安全配置
spring security常用类:
- WebSecurityConfigurerAdapter:自定义Security策略
- AuthenticationManagerBuiler:自定义认证策略
- @EnableWebSecurity:开启WebSecurity模式 (@Enablexxx注解都是开启某个功能)
SpringSecurity两个主要的目的是认证和授权(访问控制)
- 认证(Authentication)
- 授权(Authorization)
这两个概念是web安全通用的
二、SpringSecurity开发环境搭建
1、创建springboot项目,勾选web启动器
2、导入静态资源
3、在pringboot主配置文件配置调试
# 关闭模板引擎的缓存,方便调试
spring.thymeleaf.cache=false
4、编写路由controller
//跳转路由的控制器
@Controller
public class RouterController {
//首页,可以多个路径进首页,但是要用{}括起来,且,号分隔
@RequestMapping({"/","/index"})//因为这个请求映射注解可以参数为一个数组
public String index(){
return "index";
}
//登录页面路由
@RequestMapping("/login")
public String toLogin(){
return "views/login";
}
//vip1路由(请求映射地址,可以根据参数分别进三个不同页面,相当于1个请求当三个请求用)
@RequestMapping("/level1/{id}")
public String level1(@PathVariable("id") int id){
return "views/level1/"+id;
}
//vip2路由
@RequestMapping("/level2/{id}")
public String level2(@PathVariable("id") int id){
return "views/level2/"+id;
}
//vip3路由
@RequestMapping("/level3/{id}")
public String level3(@PathVariable("id") int id){
return "views/level3/"+id;
}
}
三、使用SpringSecurity
用户认证和授权
核心:AOP切面编程,就是在请求前加个拦截器
5.2.0SpringSecurity官网:https://docs.spring.io/spring-security/site/docs/5.2.0.RELEASE/reference/htmlsingle/
1、导入security启动器
<!--security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2、创建config类
继承WebSecurityConfigurerAdapter类
添加@EnableWebSecurity注解
配置,重写里面想要配置的方法
重点:认证、授权
注意密码需要添加加密方式,不然不允许访问(500error)
//AOP横切编程,不用改变原有代码,相当于拦截器
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//授权
@Override
protected void configure(HttpSecurity http) throws Exception {
//首页所有人可以访问,但是功能页只有拥有对应权限的人才能访问
//链式编程的形式
http.authorizeRequests()//授权以下请求
.antMatchers("/").permitAll()
.antMatchers("/level1/**").hasRole("vip1")
.antMatchers("/level2/**").hasRole("vip2")
.antMatchers("/level3/**").hasRole("vip3");
//没有权限默认会到登录页面,开启登录的页面
http.formLogin();//这个登录页面是security默认自带的
}
//认证
//主要密码编程(没加登录回报500):PasswordEncoder
//在springSecurity5.0+中新增了很多加密方法
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//这些数据正常应该在数据库中读,这里没连数据库,就现在内存中读。
//使用数据库的话,下面读内存inMemoryAuthentication()
//就改成读数据库jdbcAuthentication()
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
.withUser("ming").password(new BCryptPasswordEncoder().encode("123456")).roles("vip2","vip3")
.and().withUser("root").password(new BCryptPasswordEncoder().encode("777")).roles("vip1","vip2","vip3")
.and().withUser("guest").password(new BCryptPasswordEncoder().encode("666")).roles("vip1");
}
}
注销及权限控制
1、导入整合包,注意我们用的是springsecurity5.0版本,整合thymeleaf包用5.0版本
<!--security-thymeleaf4.0整合包-->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
<version>3.0.4.RELEASE</version>
</dependency>
2、导入命名空间xmlns:sec=http://www.thymeleaf.org/thymeleaf-extras-springsecurity
注意:此处命名空间地址不用加双引号和后面的版本号,不然没有代码提示。这与前面导入的整合包版本无关系,4、5都可以,就是命名空间格式问题
3、开启注销功能
4、编写前端展示
使用div分块,加入授权认证,没有登录授权认证就只显示登录连接(跳转到登录页面,记得路径改为:login)
已登录则显示用户名(和授权:vip1、vip2等),以及注销连接
5、补充:在config配置文件中关闭csrf功能,可以提升网站安全
关闭之后,注销用户他就会直接跳转到未登录状态下的首页,不会像之前一样询问是否退出登录以及跳转到登录页面那样。
6、用户不同级别显示不同的界面,原理和上面那个显示登录和注销连接一样
不过这里更简单,添加一个权限判断即可,后面两个权限判断显示原理一致
注意:hasAnyRoly()里面的参数用单引号''括起来
记住我以及首页定制
1、开启记住我功能,直接开启即可
开启记住我之后,只要没有注销的情况下关闭页面,再打开浏览器进入用户依然登录状态。
使用remember me登录后,打开网站审查元素,可以看到浏览器存在了一个cookies,并且能看到其value和失效时间默认14天,只要这14天不退出登录,就会一直存在
session(会话)和cookies的区别:
- seesion保存在服务器的,cookies保存在客服端
- session保存在服务器,cookies保存在本地浏览器
2、自定义登录页
在开启跳转登录页面代码加上loginPage和自定义请求路径即可(注意要将所有地方都该成toLogin,不然无法跳转)