🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的博客专栏《SpringBoot开发之Security系列》。🎯🎯
🎁如果感觉还不错的话请给我关注加三连吧!🎁🎁
前言
上一期的博客中我们一起学习了关于在项目中的接口测试的相关的依赖插件,可以大大提高我们的开发效率,便于我们的接口测试。今天给大家的分享是一个安全框架——Spring Security 。
一、引入
1. 什么是安全框架
安全框架是一种软件框架,旨在帮助开发人员轻松地集成安全性功能到他们的应用程序中。这些框架通常提供一系列的工具、库、API 和规范,用于处理应用程序的安全需求,包括身份验证、授权、数据保护、防御性编程等方面。安全框架的目标是简化安全性实施,提供一致的安全性管理和保护机制,从而减少开发人员在应对常见安全问题时的工作量。
其主要功能如下:
身份验证(Authentication):
- 提供一种方式来确认用户的身份,确保他们是合法的系统用户。这可能涉及用户名和密码验证、令牌验证、生物特征识别等。
授权(Authorization):
- 定义和实施用户对系统资源的访问权限。这包括确定哪些用户或角色具有对特定资源的访问权限。
加密和数据保护:
- 提供加密算法和工具,用于确保敏感信息在传输和存储过程中的安全。这包括对数据的加密、解密、数字签名等操作。
攻击防护:
- 包括对常见网络攻击(如SQL注入、跨站脚本攻击等)的预防和检测机制。这有助于保护应用程序免受常见的安全漏洞。
会话管理:
- 提供管理用户会话的机制,确保会话的安全性,防止会话劫持和会话固定攻击。
审计和监控:
- 记录安全事件、异常和用户行为,以便监控和审计系统的安全性。这有助于追踪潜在的安全问题和不寻常的活动。
单点登录(SSO):
- 允许用户一次登录即可访问多个相互信任的应用程序,提高用户体验和简化身份管理。
2. 主流安全框架
Spring Security:
Spring Security
是目前Java Web领域中最流行的框架之一,它提供了一系列安全级别,包括基于认证和授权的安全保护,以及各种各样的安全校验,使得开发人员可以非常容易地为应用程序添加安全保护。Spring Security
也提供了一种简单易用的方式来定制其过滤器链,以适应具体的安全需求。Apache Shiro:
Apache Shiro
是一个易于使用的Java Web安全框架。它提供了一种简单的方式来管理应用程序中的身份验证、授权和加密。Apache Shiro
可以轻松地集成到Spring中,并提供了一系列构建块,以便定制其安全性行为。
3. 为什么选择Spring Security
SpringBoot 没有发布之前,Shiro 应用更加广泛,因为 Shiro 是一个强大且易用的 Java 安全框架,能够非常清晰的处理身份验证、授权、管理会话以及密码加密。利用其易于理解的API,可以快速、轻松地获得任何应用程序,从最小的移动应用程序到最大的网络和企业应用程序。但是 Shiro 只是一个框架而已,其中的内容需要自己的去构建,前后是自己的,中间是Shiro帮我们去搭建和配置好的。
SpringBoot
发布后,随着其快速发展,Spring Security
(前身叫做Acegi Security
) 重新进入人们的视野。SpringBoot
解决了Spring Security
各种复杂的配置,Spring Security
在我们进行用户认证以及授予权限的时候,通过各种各样的拦截器来控制权限的访问,从而实现安全,也就是说Spring Security
除了不能脱离Spring
,Shiro
的功能它都有。
在用户认证方面,
Spring Security
框架支持主流的认证方式,包括 HTTP 基本认证、HTTP 表单验证、HTTP 摘要认证、OpenID
和LDAP
等。在用户授权方面,
Spring Security
提供了基于角色的访问控制和访问控制列表(Access Control List,ACL
),可以对应用中的领域对象进行细粒度的控制。
二、Spring Security
1. Security简介
Spring Security
是一个基于Spring
框架的安全性框架,可用于对Java应用程序进行身份验证、授权和其他安全性功能的添加。它不仅可以对Web应用程序进行保护,还可以保护非Web环境下的应用程序,如远程服务和命令行应用程序等。Spring Security
提供了一系列可插拔的安全性特性,如基于标记的身份验证、权限控制、单点登录、密码加密等。它还支持多种安全性协议和标准,如OAuth
、SAML
、OpenID
等,可与各种身份提供商集成。
2. Security的工作原理
原理概述
Spring Security是一个基于Java的框架,用于实现企业级应用程序的安全性。它提供了全面的安全服务,包括身份验证、授权、防护攻击、会话管理等功能。下面是Spring Security的主要工作原理:
过滤器链:Spring Security通过一个过滤器链来处理Web请求。在这个过程中,每个过滤器负责不同的安全任务,例如身份验证、授权、防护攻击等。过滤器链的配置是通过Java配置或XML配置完成的。
SecurityContextHolder和SecurityContext:Spring Security使用来保存安全上下文()。安全上下文包含了当前认证用户的信息,如用户名、密码、权限等。通过,开发者可以在应用程序中访问当前用户的安全信息。
SecurityContextHolder
SecurityContext
SecurityContextHolder
AuthenticationManager: 负责处理身份验证。它通常包含一个或多个身份验证提供者()。身份验证提供者根据用户提供的凭证(通常是用户名和密码)来验证用户身份。
AuthenticationManager
AuthenticationProvider
ProviderManager: 是的默认实现,它管理多个身份验证提供者。在身份验证过程中,逐个调用各个身份验证提供者,直到找到合适的提供者来完成身份验证。
ProviderManager
AuthenticationManager
ProviderManager
UserDetailsService: 接口用于加载用户信息。Spring Security通过获取用户的详细信息,包括用户名、密码、权限等。开发者可以实现这个接口来自定义用户信息的加载方式,比如从数据库中加载用户信息。
UserDetailsService
UserDetailsService
GrantedAuthority: 表示用户的权限。在Spring Security中,权限通常被表示为字符串,开发者可以通过实现接口自定义权限的表示方式。
GrantedAuthority
GrantedAuthority
AccessDecisionManager和Access Control: 用于控制用户是否有访问特定资源的权限。它依赖于注解或配置来决定用户是否有权访问某个URL或执行某个方法。
AccessDecisionManager
Access Control
<intercept-url>
CSRF防护和Session管理: Spring Security提供了CSRF(Cross-Site Request Forgery)防护机制,通过生成和验证CSRF令牌来防止CSRF攻击。同时,它还提供了对会话的管理,包括会话超时、并发会话控制等。
图示
核心组件
AuthenticationManager
:管理身份验证,可以从多种身份验证方案中选择一种。
Authentication
:用于验证用户的身份。
SecurityContextHolder
:用于管理SecurityContext
的ThreadLocal
,以便在整个请求上下文中进行访问,方便用户访问。
AccessDecisionManager
:负责对访问受保护的资源的请求进行决策(即决定是否允许用户访问资源)
AccessDecisionVoter
:是AccessDecisionManager的实现组件之一,它用于对用户请求的访问受保护的资源所需要的角色或权限进行投票。
ConfigAttribute
:用于表示受保护资源或URL需要的访问权限,它可以理解为是访问控制策略的一部分
3. 特点
Spring Security的特点如下
特点 | 说明 |
兼容性强 | Spring Security 是一个流行的开源框架,它可以与Spring应用程序完美集成。由于它的兼容性很好,因此可以非常方便地使用它保护Web应用程序。 |
功能强大 | Spring Security 具备众多功能,包括注销、登录、角色、权限、令牌、XSS 防御、CSRF 防御等等。它还支持各种身份验证、角色和权限管理方式,如基于表单的认证、基于记住我功能的认证以及OAuth 认证等等。 |
安全可靠 | Spring Security 具有极高的安全性,它使用最新的安全标准和协议来保护Web应用程序。Spring Security 采用安全性分层的策略来保护应用程序中的各个层,例如Web 层、Service 层、DAO 层等等。除此之外,Spring Security 还支持自定义安全策略和事件响应,从而使得开发者可以根据应用程序需求定制安全保护。 |
易于使用 | Spring Security 提供了一种高度简化的方式来保护Web应用程序。它使用简单的标签和安全注解来添加安全保护,从而使得开发者可以基本不需要手动编写代码就可以完成安全保护。 |
社区广泛 | Spring Security 是一个著名的开源框架,因此它有一个庞大的用户社区。这个社区不仅提供了大量的文档、示例和教程,而且还会解答开发者的问题、修复框架中的BUG等等。这为开发者提供了无限的支持和帮助,从而可以使用Spring Security 更加自信。 |
三、Web安全配置类
4.1.HttpSecurity介绍
HttpSecurity
是Spring Security
的一个核心类,用于配置应用程序的安全策略。
HttpSecurity
类通常包含许多方法,可以用于配置以下内容:
HTTP 请求的安全策略,例如访问控制、跨站点请求伪造 (CSRF) 防护等。
HTTP 验证的安全策略,例如基于表单、HTTP 基本身份验证、OAuth 等。
访问受保护资源时所需的身份验证和授权方式。
方法 | 说明 |
---|---|
authorizeRequests() | 用于配置如何处理请求的授权,默认情况下所有的请求都需要进行认证和授权才能访问受保护的资源 |
formLogin() | 用于配置基于表单的身份验证,包括自定义登录页面、登录请求路径、用户名和密码的参数名称、登录成功和失败的跳转等。 |
httpBasic() | 用于配置基于HTTP Basic 身份验证,包括定义使用的用户名和密码、realm 名称等。 |
logout() | 用于配置退出登录功能,包括定义退出登录请求的URL、注销成功后的跳转URL、清除会话、删除Remember-Me 令牌等。 |
csrf() | 用于配置跨站请求伪造保护,包括定义CSRF Token 的名称、保存方式、忽略某些请求等。 |
sessionManagement() | 用于配置会话管理,包括定义并发控制、会话失效、禁用URL重定向、会话固定保护等。 |
rememberMe() | 用于配置Remember-Me 功能,包括定义Remember-Me 令牌的名称、有效期、加密方法、登录成功后的处理方式等。 |
exceptionHandling() | 用于配置自定义的异常处理,包括定义异常处理器和异常处理页面等。 |
headers() | 用于配置HTTP响应头信息,包括定义X-Content-Type-Options、X-XSS-Protection、Strict-Transport-Security 等头信息。 |
cors() | 用于配置跨域资源共享,包括定义可访问的来源、Headers 等。 |
addFilter() | 用于向当前HttpSecurity 中添加自定义的Filter 。 |
and() | 用于在配置中添加另一个安全规则,并将两个规则合并。 |
匹配规则:
-
URL匹配
方法 | 说明 |
---|---|
requestMatchers() | 配置一个request Mather 数组,参数为RequestMatcher 对象,其match 规则自定义,需要的时候放在最前面,对需要匹配的的规则进行自定义与过滤 |
authorizeRequests() | URL权限配置 |
antMatchers() | 配置一个request Mather 的string 数组,参数为ant 路径格式, 直接匹配url |
anyRequest() | 匹配任意url ,无参 ,最好放在最后面 |
-
保护URL
方法 | 说明 |
---|---|
authenticated() | 保护Url ,需要用户登录 |
permitAll() | 指定URL无需保护,一般应用与静态资源文件 |
hasRole(String role) | 限制单个角色访问 |
hasAnyRole(String… roles) | 允许多个角色访问 |
access(String attribute) | 该方法使用 SPEL , 所以可以创建复杂的限制 |
hasIpAddress(String ipaddressExpression) | 限制IP 地址或子网 |
-
登录formLogin
方法 | 说明 |
---|---|
loginPage() | 设置登录页面的 URL |
defaultSuccessUrl() | 设置登录成功后的默认跳转页面 |
failuerHandler() | 登录失败之后的处理器 |
successHandler() | 登录成功之后的处理器 |
failuerUrl() | 登录失败之后系统转向的url ,默认是this.loginPage + “?error” |
loginProcessingUrl() | 设置登录请求的 URL,即表单提交的 URL |
usernameParameter() | 设置登录表单中用户名字段的参数名,默认为 username |
passwordParameter() | 设置登录表单中密码字段的参数名,默认为 password |
-
登出logout
方法 | 说明 |
---|---|
logoutUrl() | 登出url , 默认是/logout l |
logoutSuccessUrl() | 登出成功后跳转的 url 默认是/login?logout |
logoutSuccessHandler() | 登出成功处理器,设置后会把logoutSuccessUrl 置为null |
四、Spring集成Security使用
首先我们创建一个新的SpringBoot项目
准备工作
导入页面样式文件
1. 引入pom依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</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-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency>
2. 配置application.yml
文件
server:port: 8080
spring:freemarker:# 设置freemarker模板后缀suffix: .ftl# 设置freemarker模板前缀template-loader-path: classpath:/templates/enabled: true
3. 编写控制层
UserController.java
package com.yx.security.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class UserController {@RequestMapping("/toLogin")public String toLogin() {return "login";}@RequestMapping("/userLogin")public String userLogin(String username, String password) {System.out.println("username=" + username + ",password=" + password);return "index";}@RequestMapping("/admin/toAddUser")public String toAddUser() {return "admin/addUser";}@RequestMapping("/admin/toListUser")public String toListUser() {return "admin/listUser";}@RequestMapping("/admin/toResetPwd")public String toResetPwd() {return "admin/resetPwd";}@RequestMapping("/admin/toUpdateUser")public String toUpdateUser() {return "admin/updateUser";}@RequestMapping("/user/toUpdatePwd")public String toUpdatePwd() {return "user/updatePwd";}@RequestMapping("/noAccess")public String noAccess() {return "accessDenied";}}
初步访问
我们到这一步就可以直接启动项目运行。
我们在浏览器上直接访问项目
默认的用户名是user,密码是控制台生成的字符串
初步使用
1. 创建SecurityConfig配置类
WebSecurityConfig.java
package com.yx.security.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;@Configuration
//开启SpringSecurity的默认行为
@EnableWebSecurity
public class WebSecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http)throws Exception{http.authorizeRequests()// 开放接口访问权限,不需要登录就可以访问.antMatchers("/","/hello","/toLogin").permitAll()// 其余所有请求全部需要鉴权认证.anyRequest().authenticated();return http.build(); }
}
配置完毕之后,请重启项目访问主页页面进行测试,除了开放接口能正常访问以外,其他接口均提示403错误
我们对配置类进行了一定的修改所以除了开发的 开放接口能正常访问以外,其他接口均提示错误。
2. 配置类进行一系列修改配置
如果现在直接运行访问项目进行登陆是无法跳转的 需要添加下述代码
http.csrf().disable();
添加之后重新登陆就可以访问,使用其他账号访问不了
3. 访问网址
由上图可知我们登陆user用户点击管理员权限时报错,登陆admin管理员身份再次的点击跳转页面,这是我们权限设置的效果。为例普通用户点击管理员权限功能不报错我们设置跳转其他页面。
配置自定义异常处理器
我们再去测试效果如下
下面是我们退出登陆的设置,退出登陆注销当前用户
由上图所示当我们退出登陆时,在返回上一个页面是回不去了,这就是退出注销用户。
🎉🎉本期的博客分享到此结束🎉🎉
📚📚各位老铁慢慢消化📚📚
🎯🎯下期博客博主会带来新货🎯🎯
🎁三连加关注,阅读不迷路 !🎁