前言

在 Web 开发中,安全一直是非常重要的一个方面。安全虽然属于应用的非功能性需求,但是应该在应用开发的初期就考虑进来。Spring Security是针对Spring项目的安全框架,也是Spring Boot底层安全模块默认的技术选型。他可以实现强大且高度可定制的身份认证和访问控制。我们仅需引入spring-boot-starter-security模块,进行少量的配置,即可实现强大的安全管理。

一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分。用户认证指的是验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。

对于上面提到的两种应用情景,Spring Security 框架都有很好的支持。在用户认证方面,Spring Security 框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID 和 LDAP 等。在用户授权方面,Spring Security 提供了基于角色的访问控制和访问控制列表(Access Control List,ACL),可以对应用中的领域对象进行细粒度的控制。

一、搭建环境

1)新建一个项目,导入web和thymeleaf模块
2)把准备好的页面放入templates文件夹,创建一个Controller
welcome.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">欢迎光临武林秘籍管理系统</h1>
<h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/login}">请登录</a></h2>
<hr><h3>普通武功秘籍</h3>
<ul><li><a th:href="@{/level1/1}">罗汉拳</a></li><li><a th:href="@{/level1/2}">武当长拳</a></li><li><a th:href="@{/level1/3}">全真剑法</a></li>
</ul><h3>高级武功秘籍</h3>
<ul><li><a th:href="@{/level2/1}">太极拳</a></li><li><a th:href="@{/level2/2}">七伤拳</a></li><li><a th:href="@{/level2/3}">梯云纵</a></li>
</ul><h3>绝世武功秘籍</h3>
<ul><li><a th:href="@{/level3/1}">葵花宝典</a></li><li><a th:href="@{/level3/2}">龟派气功</a></li><li><a th:href="@{/level3/3}">独孤九剑</a></li>
</ul></body>
</html>

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body><h1 align="center">欢迎登陆武林秘籍管理系统</h1><hr><div align="center"><form action="" method="post">用户名:<input name=""/><br>密码:<input name=""><br/><input type="submit" value="登陆"></form></div>
</body>
</html>

Controller

@Controller
public class KungfuController {private final String PREFIX = "pages/";/*** 欢迎页* @return*/@GetMapping("/")public String index() {return "welcome";}/*** 登陆页* @return*/@GetMapping("/userlogin")public String loginPage() {return PREFIX+"login";}/*** level1页面映射* @param path* @return*/@GetMapping("/level1/{path}")public String level1(@PathVariable("path")String path) {return PREFIX+"level1/"+path;}/*** level2页面映射* @param path* @return*/@GetMapping("/level2/{path}")public String level2(@PathVariable("path")String path) {return PREFIX+"level2/"+path;}/*** level3页面映射* @param path* @return*/@GetMapping("/level3/{path}")public String level3(@PathVariable("path")String path) {return PREFIX+"level3/"+path;}
}

3)测试实验环境是否OK!

二、认证和授权

记住几个类:
WebSecurityConfigurerAdapter:自定义Security策略
AuthenticationManagerBuilder:自定义认证策略
@EnableWebSecurity:开启WebSecurity模式
Spring Security的两个主要目标是 “认证” 和 “授权”(访问控制)

1.导入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

2.编写 Spring Security 配置类

@EnableWebSecurity // 开启WebSecurity模式
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {}
}

3.定制请求的授权规则

@EnableWebSecurity // 开启WebSecurity模式
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//super.configure(http);//定制权限规则http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/level1/**").hasRole("VIP1").antMatchers("/level2/**").hasRole("VIP2").antMatchers("/level3/**").hasRole("VIP3");}
}

4.开启自动配置的登录功能

@EnableWebSecurity // 开启WebSecurity模式
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//super.configure(http);//定制权限规则http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/level1/**").hasRole("VIP1").antMatchers("/level2/**").hasRole("VIP2").antMatchers("/level3/**").hasRole("VIP3");//自动配置登录功能/** 1.默认发送/login get请求,来到默认的登录页面* 2.没有登录没有权限也会默认发送/login get请求跳到默认登录页面* 3.自定义loginPage请求必须同时自定义处理controller* 4.loginProcessingUrl方法自定义form表单提交请求,默认是${login} post* 5.默认参数是username和password* 6.认证失败重定向/${login}?error,默认是login?error* 7.认证成功返回到登录页面前的页面*/http.formLogin();}
}

这时,点击欢迎页的登录或者点击没有权限访问的链接时,都会跳转到登录的页面!

5.定义认证规则

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {//定义认证规则@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {//super.configure(auth);//5.0之前的版本
//      auth.inMemoryAuthentication()
//              .withUser("zhangsan").password("123456").roles("VIP1","VIP2")
//              .and().withUser("lisi").password("123456").roles("VIP2","VIP3")
//              .and().withUser("wangwu").password("123456").roles("VIP1","VIP3");//5.0之后的版本,需要加密auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()).withUser("zhangsan").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1","VIP2").and().withUser("lisi").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP2","VIP3").and().withUser("wangwu").password(new BCryptPasswordEncoder().encode("123456")).roles("VIP1","VIP3");}
}

6.开启默认退出功能

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//super.configure(http);//定制权限规则http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/level1/**").hasRole("VIP1").antMatchers("/level2/**").hasRole("VIP2").antMatchers("/level3/**").hasRole("VIP3");//自动配置登录功能/** 1.默认发送/login get请求,来到默认的登录页面* 2.没有登录没有权限也会默认发送/login get请求跳到默认登录页面* 3.自定义loginPage请求必须同时自定义处理controller* 4.loginProcessingUrl方法自定义form表单提交请求,默认是${login} post* 5.默认参数是username和password* 6.认证失败重定向/${login}?error,默认是login?error* 7.认证成功返回到登录页面前的页面***/http.formLogin();//loginPage("/userlogin").loginProcessingUrl("/login");//退出/**1.发送/logout,清除session,默认成功重定向到/login?logout* 2.logoutSuccessUrl自定义退出后的页面*/http.logout().logoutSuccessUrl("/");//关闭csrf功能//http.csrf().disable();}
}

定义一个退出表单,发送/logout post请求

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">欢迎光临武林秘籍管理系统</h1>
<h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/login}">请登录</a></h2>
<form th:action="@{/logout}" method="post"><input type="submit" value="退出"/>
</form>
<hr><h3>普通武功秘籍</h3>
<ul><li><a th:href="@{/level1/1}">罗汉拳</a></li><li><a th:href="@{/level1/2}">武当长拳</a></li><li><a th:href="@{/level1/3}">全真剑法</a></li>
</ul><h3>高级武功秘籍</h3>
<ul><li><a th:href="@{/level2/1}">太极拳</a></li><li><a th:href="@{/level2/2}">七伤拳</a></li><li><a th:href="@{/level2/3}">梯云纵</a></li>
</ul><h3>绝世武功秘籍</h3>
<ul><li><a th:href="@{/level3/1}">葵花宝典</a></li><li><a th:href="@{/level3/2}">龟派气功</a></li><li><a th:href="@{/level3/3}">独孤九剑</a></li>
</ul></body>
</html>

7.权限控制

引入依赖

   <dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity5</artifactId><version>3.0.4.RELEASE</version></dependency>

导入命名空间

xmlns:sec="http://www.thymeleaf.org/extras/spring-security"

修改欢迎页如下

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">欢迎光临武林秘籍管理系统</h1>
<div sec:authorize="!isAuthenticated()"><h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/login}">请登录</a></h2>
</div>
<div sec:authorize="isAuthenticated()"><h2 align="center"><span sec:authentication="name"></span>您好,您的角色有:<span sec:authentication="principal.authorities"></span></h2><form th:action="@{/logout}" method="post"><input type="submit" value="注销"/></form>
</div><hr><div sec:authorize="hasRole('VIP1')"><h3>普通武功秘籍</h3><ul><li><a th:href="@{/level1/1}">罗汉拳</a></li><li><a th:href="@{/level1/2}">武当长拳</a></li><li><a th:href="@{/level1/3}">全真剑法</a></li></ul>
</div><div sec:authorize="hasRole('VIP2')"><h3>高级武功秘籍</h3><ul><li><a th:href="@{/level2/1}">太极拳</a></li><li><a th:href="@{/level2/2}">七伤拳</a></li><li><a th:href="@{/level2/3}">梯云纵</a></li></ul>
</div><div sec:authorize="hasRole('VIP3')"><h3>绝世武功秘籍</h3><ul><li><a th:href="@{/level3/1}">葵花宝典</a></li><li><a th:href="@{/level3/2}">龟派气功</a></li><li><a th:href="@{/level3/3}">独孤九剑</a></li></ul></div></body>
</html>

7.记住我

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//记住我功能,cookie默认保存两周http.rememberMe();}

8.定制登录页

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {//自动配置登录功能/** 1.默认发送/login get请求,来到默认的登录页面* 2.没有登录没有权限也会默认发送/login get请求跳到默认登录页面* 3.自定义loginPage请求必须同时自定义处理controller* 4.loginProcessingUrl方法自定义form表单提交请求,默认是${login} post* 5.默认参数是username和password* 6.认证失败重定向/${login}?error,默认是login?error* 7.认证成功返回到登录页面前的页面*/http.formLogin().loginPage("/userlogin").usernameParameter("user").passwordParameter("pwd").loginProcessingUrl("/login");//退出/**1.发送/logout,清除session,默认成功重定向到/login?logout* 2.logoutSuccessUrl自定义退出后的页面*/http.logout().logoutSuccessUrl("/");//关闭csrf功能//http.csrf().disable();//记住我功能,cookie默认保存两周http.rememberMe();}

则来到登录页面的请求应该改成/userlogin

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">欢迎光临武林秘籍管理系统</h1>
<div sec:authorize="!isAuthenticated()"><h2 align="center">游客您好,如果想查看武林秘籍 <a th:href="@{/userlogin}">请登录</a></h2>
</div>

并且自定义controller处理这个请求

 /*** 登陆页* @return*/@GetMapping("/userlogin")public String loginPage() {return PREFIX+"login";}

而提交表单的请求应改成/login

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body><h1 align="center">欢迎登陆武林秘籍管理系统</h1><hr><div align="center"><form th:action="@{/login}" method="post">用户名:<input name="user"/><br>密码:<input name="pwd"><br/><input type="submit" value="登录"></form></div>
</body>
</html>

9.自定义rememberMe

因为我们现在使用自定义的登录页面,所以需要自己定义rememberMe
在login页面表单加入

<input type="checkbox" name="remeber-me">记住我<br/>

后台代码修改成

http.rememberMe().rememberMeParameter("remeber-me");

SpringBoot2--Spring Security相关推荐

  1. springboot2 war页面放在那_Spring Boot2 系列教程(三十三)整合 Spring Security

    Spring Security 是 Spring 家族中的一个安全管理框架,实际上,在 Spring Boot 出现之前,Spring Security 就已经发展了多年了,但是使用的并不多,安全管理 ...

  2. Spring Security整合JWT,实现单点登录,So Easy~!

    前面整理过一篇 SpringBoot Security前后端分离,登录退出等返回json数据,也就是用Spring Security,基于SpringBoot2.1.4 RELEASE前后端分离的情况 ...

  3. spring security reactive获取security context

    为什么80%的码农都做不了架构师?>>>    序 本文主要研究下reactive模式下的spring security context的获取. ReactiveSecurityCo ...

  4. Spring Boot+Vue/前后端分离/高并发/秒杀实战课程之spring Security快速搭建oauth2 内存版身份认证

    Springboot快速搭建oauth2 内存版身份认证 环境准备 点击[Create New Project]创建一个新的项目 项目环境配置 配置Thymeleaf 搭建oauth2认证,加入两个依 ...

  5. SpringBoot第二十三篇:安全性之Spring Security

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11350255.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   系统的安全 ...

  6. SpringBoot + Spring Security 学习笔记(一)自定义基本使用及个性化登录配置

    官方文档参考,5.1.2 中文参考文档,4.1 中文参考文档,4.1 官方文档中文翻译与源码解读 SpringSecurity 核心功能: 认证(你是谁) 授权(你能干什么) 攻击防护(防止伪造身份) ...

  7. spring boot整合spring security笔记

    最近自己做了一个小项目,正在进行springboot和spring Security的整合,有一丢丢的感悟,在这里分享一下: 首先,spring boot整合spring security最好是使用T ...

  8. Spring Security 实战干货:自定义异常处理

    Spring Security 实战干货:自定义异常处理 转自:https://www.cnblogs.com/felordcn/p/12142514.html 文章目录 1. 前言 2. Sprin ...

  9. Spring security防止跨站请求伪造(CSRF防护)

    因为使用了spring security 安全性框架 所以spring security 会自动拦截站点所有状态变化的请求(非GET,HEAD,OPTIONS和TRACE的请求),防止跨站请求伪造(C ...

  10. 【Spring Security】五、自定义过滤器

    在之前的几篇security教程中,资源和所对应的权限都是在xml中进行配置的,也就在http标签中配置intercept-url,试想要是配置的对象不多,那还好,但是平常实际开发中都往往是非常多的资 ...

最新文章

  1. iOS端Socket连接、发送数据(一)
  2. Web service是什么?
  3. python自然语言处理.词性标注
  4. flask 第八篇 实例化flask时的参数配置
  5. OpenCV+python实现视频文件读写
  6. Java 进阶:集合框架2
  7. Fluent Ribbon项目出现“命名空间“clr-namespace:Fluent;assembly=Fluent”中不存在“RibbonWindow”名称”的解决方法...
  8. 一念逍遥服务器维护,一念逍遥开服攻略 新手开荒技巧
  9. centos系统的Visual Studio code卡死,无法选择或者输入
  10. 嵌入式 博客导航大牛群集
  11. 破解入门(八)-----算法分析与注册机编写
  12. VM虚拟机BT5下对usb无线网卡的配置
  13. springboot使用j2cache
  14. 初中计算机卡片的制作教案,【我的拼音卡片教案】制作拼音卡片
  15. axure rp pro入门
  16. 【集合论】关系表示 ( 关系矩阵 | 关系矩阵示例 | 关系矩阵性质 | 关系矩阵运算 | 关系图 | 关系图示例 | 关系表示相关性质 )
  17. js数字金额转大写,javaScript数字金额转大写。
  18. Chrome浏览器升级80以后导致重定向自动登录失效问题记录和解决方案
  19. 【Office使用技巧】word内公式相关快捷键
  20. War3地图编辑器基础:玩家设置+地图元素的属性设置+地图事件设置

热门文章

  1. vector sort排序 —— cmp 写法
  2. C# + PHP RSA保密通讯
  3. 钉钉、微信抢占移动OA入口,其他OA厂商何去何从?
  4. BAPC 2019 G. Gluttonous Goop 线段树扫描线
  5. 【更新】Project 读写管理控件Aspose.Tasks V17.5发布 | 附下载
  6. 关于《管理:技艺之精髓》一书中提到的管理任务和工具
  7. 元数据管理工具Atlas学习笔记之集成
  8. 谷歌地图接口Google Maps APIs中地图样式设计配置调整与JSON或URL导出
  9. linux命令大全 pwd,linux操作系统pwd的基本语法
  10. Hive 中的各种常用set设置