Skip to main content

moregeek program

spring security:用户和spring应用之间的安全屏障_华为云开发者社区的博客-多极客编程

摘要:Spring Security是一个安全框架,作为Spring家族的一员。

本文分享自华为云社区《​​【云驻共创】深入浅出Spring Security​​》,作者:香菜聊游戏。

一、前言

1.历史

Spring Security最早叫Acegi Security,这个名称并不是说它和Spring就没有关系,它依然是为Spring框架提供安全支持的。Acegi Security基于Spring,可以帮助我们为项目建立丰富的角色与权限管理系统。Acegi Security虽然好用,但是最为人诟病的则是它臃肿繁琐的配置,这一问题最终也遗传给了Spring Security。Acegi Security最终被并入Spring Security项目中,并于2008年4月发布了改名后的第一个版本Spring Security 2.0.0。

Spring Security:用户和Spring应用之间的安全屏障_Spring Security

2.对比

和Shiro相比,Spring Security重量级并且配置繁琐。其实自从Spring Boot推出后,就彻底颠覆了传统了JavaEE开发,自动化配置让许多事情变得非常容易。在一个Spring Boot项目中,我们甚至只需要引入一个依赖,不需要任何额外配置,项目的所有接口就会被自动保护起来了。在Spring Cloud中很多涉及安全管理的问题,也是一个Spring Security依赖两行配置就能搞定,在和Spring家族的产品一起使用时,Spring Security的优势就非常明显了。因此在微服务时代,我们不需要纠结要不要学习Spring Security,我们要考虑的是如何快速掌握Spring Security,并且能够使用Spring Security实现我们微服务的安全管理。

3.为什么选择

不同于其他领域,在Java企业级开发中,安全管理方面的框架非常少,一般来说,主要有三种方案:

• Shiro

• Spring Security

• 开发者自己实现

Shiro本身是一个老牌的安全管理框架,有着众多的优点,例如轻量、简单、易于集成,可以在JavaSE环境中使用等。不过在微服务面前,它无法充分展示自己的优势。也有开发者选择自己实现安全管理,不过一个系统的安全,不仅仅是登录和权限控制这么简单,我们还要考虑各种各样可能存在的网络攻击以及防御策略,从这个角度来说,只有大公司才有足够的人力物力去支持这件事情。 Spring Security作为Spring家族的一员,在和Spring家族的其他成员进行整合时,具有其他框架无可比拟的优势,同时对OAuth2有着良好的支持,再加上Spring Cloud对Spring Security的不断加持,让Spring Security成为微服务项目的首选安全管理方案。

二、Spring Security简介

Spring Security的核心功能

对于一个安全管理框架而言,无论是Shiro还是Spring Security,最核心的功能,无非就是如下两方面认证和授权。

1.认证

认证就是身份验证(你是谁?),作为一个开放的平台,我们还可以通过引入第三方依赖来支持更多的认证方式,同时,如果这些认证方式无法满足我们的需求,我们也可以自定义认证逻辑,特别是当我们和一些“老破旧”的系统进行集成时,自定义 认证逻辑就显得非常重要了。

2.授权

授权就是访问控制(你可以做什么?),无论采用了哪种认证方式,都不影响在Spring Security中使用授权功能。Spring Security支持基于URL的请求授权、支持方法访问授权、支持SpEL访问控制、支持域对象安全(ACL),同时也支持动态权限配置、支持RBAC权限模型等,总之我们常见的权限管理需求,Spring Security基本上都是支持的。

3.其他

在认证和授权这两个核心功能之外,Spring Security还提供了很多安全管理的“周边功能”,这也是一个非常重要的特色,例如:

• 密码加密

• RememberMe

• 会话固定攻击防御

• CSRF防御

• Http防火墙

Spring Security 的整体架构

Spring Security:用户和Spring应用之间的安全屏障_ide_02

1.认证和授权

在Spring Security的架构设计中,认证(Authentication)和授权(Authorization)是分开的,无论使用什么样的认证方式,都不会影响授权,这是两个独立的存在,这种独立带来的好处之一,就是Spring Security可以非常方便地整合一些外部的认证方案。在Spring Security中,用户的认证信息主要由Authentication的实现类来保存,当用户使用用户名/密码登录或使用Remember-me登录时,都会对应一个不同的Authentication实例。Spring Security中的认证工作主要是由AuthenticationManager接口来负责,在该接口中通过authenticate方法来做认证。AuthenticationManager最主要的实现类是ProviderManager,ProviderManager管理了众多的 AuthenticationProvider实例。在一次完整的认证流程中,可能会同时存在多个AuthenticationProvider,多个AuthenticationProvider统一由ProviderManager来管理。同时,ProviderManager具有一个可选的parent,如果所有的AuthenticationProvider都认证失败,那么就会调用parent进行认证。

2.关键接口

在Spring Security的授权体系中,有两个关键接口: AccessDecisionManager 和AccessDecisionVoter。

AccessDecisionVoter是一个投票器,投票器会检查用户是否具备应有的角色,进而投出赞成、反对或者弃权票。

AccessDecisionManager则是一个决策器,来决定此次访问是否被允许。

3.Web安全

在Spring Security中,认证、授权等功能都是基于过滤器来完成的。开发者所见到的Spring Security提供的功能,都是通过这些过滤器来实现的,这些过滤器按照既定的优先级排列,最终形成一个过滤器链。开发者也可以自定义过滤器,并通过@Order注解去调整自定义过滤器在过滤器链中的位置。需要注意的是,默认过滤器并不是直接放在Web项目的原生过滤器链中,而是通过一个FilterChainProxy来统一管理。Spring Security中的过滤器链通过FilterChainProxy嵌入到Web项目的原生过滤器链中。在Spring Security中,这样的过滤器链不仅仅只有一个可能会有多个。当存在多个过滤器链时,多个过滤器链之间要指定优先级,当请求到达后,会从FilterChainProxy进行分发,先和哪个过滤器链匹配上,就用哪个过滤器链进行处理。

Spring Security:用户和Spring应用之间的安全屏障_ide_03

三、Spring Security认证流程分析

1.基本认证

在Spring Boot项目中使用Spring Security非常方便,创建一个新的SpringBoot项目,我们只需要引入web和Spring Security依赖即可。

Maven 项目加入下面的依赖

Spring Security:用户和Spring应用之间的安全屏障_Spring Security_04

引入依赖后,项目中的所有接口就都被保护起来了,此时访问接口就可以看到登录页面了。

Spring Security:用户和Spring应用之间的安全屏障_Spring Security_05

2.Spring Security认证流程分析

Spring Security:用户和Spring应用之间的安全屏障_Spring Security_06

AuthenticationManafer是一个认证管理器。它定义了Spring Security过滤器要如何执行认证操作,在认证成功后,会返回一个Authentication对象,这个对象会被设置到SecurityContextHodler中。AuthenticationManafer是一个接口,它有着诸多的实现类,开发者可以自定义AuthenticationManafer的实现类,不过在实际应用中,我们使用最多的是ProviderManager,在Spring Security框架中,默认也是使用ProviderManager。

1)AuthentucationProvider

Spring Security支持多种不同的认证方式,不同的认证方式对应不同的身份类型,AuthentucationProvider就是针对不同的身份类型执行具体的身份认证。例如,常见的DaoAuthenticationProvider用来支持用户名密码登录认证, RememberMeAuthenticationProvider用来支持记住我的认证。

2)ProviderManager

在Spring Security中,由于系统可能同时支持多种不同的认证方式,例如同时支持用户名/密码认证、RememberMe认证、手机号码动态认证等,而不同的认证方式对应了不同的AuthenticationProvider,所以一个完整的认证流程可能由多个AuthenticationProvider来提供。多个AuthenticationProvider将组成一个列表这个列表将由ProviderManagerf代理。换句话说,在ProviderManager中存在一个AuthenticationProvider表在ProviderManager中遍历列表中的每一个AuthenticationProvider去执行身份认证,最终得到认证结果。ProviderManager本身也可以再配置一个AuthenticationManager作为parent,这样当ProviderManager认证失败之后,就可以进入到parent中再次进行认证。理论上来说,ProviderManager的parent可以是任意类型的AuthenticationManager,但是通常都是由ProviderManager来扮演parent的角色,也就是ProviderManager是ProviderManager的parent。

Spring Security:用户和Spring应用之间的安全屏障_防火墙_07

3)AbstractAuthenticationProcessingFilter

AbstractAuthenticationProcessingFilter用来处理任何提交给它的身份认证。

Spring Security:用户和Spring应用之间的安全屏障_spring_08

四、Spring Security密码加密

1.常见实现类

BcryptPasswordEncoder

Argon2PasswordEncoder

Pbkdf2PasswordEncoder

ScryptPasswordEncoder

2.DelegatingPasswordEncoder

DelegatingPasswordEncoder是一个代理类,而并非一种全新的密码加密方案。主要用来代理不同的密码加密方案。为什么采用而不是某一个具体加密方式作为默认的密码加密方案呢?主要考虑了如下三方面的因素:

(1)兼容性:使用DelegatingPasswordEncoder可以帮助许多使用旧密码加密方式的系统顺利迁移到中,它允许在同一个系统中同时存在多种不同的密码加密方案。

(2)便捷性:密码存储的最佳方案不可能一直不变,如果使用DelegatingPasswordEncoder作为默认的密码加密方案,当需要修改加密方案时,只需要修改很小一部分代码就可以实现。

(3)稳定性:作为一个框架,不能经常进行重大更改,而使用DelegatingPasswordEncoder可以方便地对密码进行升级(自动从一个加密方案升级到另外一个加密方案)。

五、Spring Security会话管理

1.什么是会话

当浏览器调用登录接口登录成功后,服务端会和浏览器之间建立一个会话(Session),浏览器在每次发送请求时都会携带一个SessionId,服务端则根据这个SessionId来判断用户身份。当浏览器关闭后,服务端的Session并不会自动销毁,需要开发者手动在服务端调用Session销毁方法,或者等Session过期时间到了自动销毁。在Spring Security中,与HttpSession相关的功能由 SessionManagementFilter和SessionAuthenticationStrategy接口来处理, 过滤器将Session相关操作委托给SessionAuthenticationStrategy接口去完成。

2.什么是会话并发管理?

会话并发管理就是指在当前系统中,同一个用户可以同时创建多少个会话,如果一台设备对应一个会话,那么也可以简单理解为同一个用户可以同时在多少台设备上进行登录。默认情况下,同一用户在多少台设备上登录并没有限制,不过开发者可以在Spring Security中对此进行配置。

3.挤下线

当会话并发数达到限制时,新的会话将之前旧的会话挤下线,旧的登录会话失效。配置如下

Spring Security:用户和Spring应用之间的安全屏障_防火墙_09

4.限制登录

当会话并发数达到限制时,新的会话将被限制创建,除非旧的会话主动退出登录。

Spring Security:用户和Spring应用之间的安全屏障_ide_10

5.什么是会话固定攻击

会话固定攻击(Session fixation attacks)是一种潜在的风险,恶意攻击者有可能通过访问当前应用程序来创建会话,然后诱导用户以相同的会话登录(通常是将会话作为参数放在请求链接中,然后诱导用户去单击),进而获取用户的登录身份。

1.会话固定攻击步骤

(1)攻击者自己可以正常访问javaboy网站,在访问的过程中,网站给攻击者分配了一个。

(2)攻击者利用自己拿到的sessionId构造一个javaboy网站的链接,并把该链接发送给受害者。

(3)受害者使用该链接登录javaboy网站(该链接中含有sessionId),登录成功后,一个合法的会话就成功建立了。

(4)攻击者利用手里的冒充受害者。

2.会话固定攻击防御策略

Spring Security中从三方面入手防范会话固定攻击:

(1)Spring Security中默认自带了Http防火墙,如果sessionId放在地址栏中,这个请求就会直接被拦截下来。

(2)在http响应的Set-Cookie字段中有HttpOnly属性,这样避免了通过XSS攻击来获取Cookie中的会话信息, 进而达成会话固定攻击。

(3)在用户登录成功后,改变SessionId, Spring Security中默认实现了该种方案。

六、Spring Security防火墙

1.什么是HttpFireWall

HttpFirewall是Spring Security提供的Http防火墙,它可以用于拒绝潜在的危险请求或者包装这些请求进而控制其行为。通过可以对各种非法请求提前进行拦截并处理,降低损失。

2.Spring Security 中的HttpFirewall两个实现类

Spring Security:用户和Spring应用之间的安全屏障_spring_11

• DefaultHttpFirewall虽然名字中包含Default,但这并不是框架默认使用的Http防火墙,它只是一个检查相对宽松的防火墙。

HttpFirewall普通模式就是使用DefaultHttpFirewall,该类的校验规则就要简单很多。一般来说,并不建议开发者在项目中使用DefaultHttpFirewall,因为相比于StrictHttp Firewal,DefaultHttpFirewall的安全性要差很多。

• StricHttpFirewall 这是一个检查严格的Http防火墙,也是框架默认使用的 Http防火墙

严格模式下对请求做出了诸多限制:

1) rejectForbiddenHttpMethod:校验请求方法是否合法。

2)rejectedBlacklistedUrls:校验请求中的非法字符。

3) rejectedUntrustedHosts:检验主机信息。

4)isNormalized:判断参数格式是否合法。

5)containsOnlyPrintableAsciCharacters: 判断请求字符是否合法。

总结

Spring Security是一个安全框架,作为Spring家族的一员,可以简单地认为 Spring Security是放在用户和Spring应用之间的一个安全屏障,每一个web请求都先要经过Spring Security 进行Authenticate和 Authoration验证,其核心就是一组过滤器链。


​点击关注,第一时间了解华为云新鲜技术~​

©著作权归作者所有:来自51CTO博客作者华为云开发者联盟的原创作品,如需转载,请与作者联系,否则将追究法律责任
Spring Security:用户和Spring应用之间的安全屏障
https://blog.51cto.com/u_15214399/5395816

基于grpc从零开始搭建一个准生产分布式应用(3) - GRPC实现-多极客编程

本章开始会进入GRPC子专题,先实现前面章节中提到的例子。然后就使用的知识点展开全面的描述。本章代码任务:1、实现一个简单的GRPC服务;2、实现GRPC拦截器。本章的代码承接上一章的代码进行迭代。因模块间存在相互依赖关系,读者一定先按笔者讲述的顺序操作,否则最后程序可能由于依赖问题导致不能运行;一、准备工作因为本专题定位于准生产环境,所以我们在代码上也会按规范严格要求一下,本章涉及的准备工作就是

软件设计文档最容易忽略内容看这里!-多极客编程

如果你是软件开发人员或架构师,一定知道开发行业里普遍存在这样一种“文档纠结症”:一面抱怨写文档浪费时间,一面抱怨别人不写文档。可以说,设计文档可以说是日常工作中非常重要但又容易被忽略的部分。编写软件设计文档(SDD)的好处很多,其主要目的是使开发者对软件设计进行强制性思考, 并收集他人的反馈, 以便更好地完成工作。同时也是让其他人了解系统的参考文档。好的文档与项目成功之间有很强的关联性。相信很多网

手把手教你实战开发黑白棋实时对战游戏-多极客编程

摘要:本次实践可以体验到全程在云上创建弹性云服务器ECS,配置云服务器环境,在DevCloud平台上一站式进行项目管理、代码托管、代码检查、流水线、编译、构建、部署、测试、发布的流程。本文分享自华为云社区《​​基于DevCloud进行黑白棋实时对战游戏开发实践【华为云至简致远】​​》,作者:gentle_zhou 。本文基于DevCloud进行黑白棋实时对战游戏开发,沙箱实验链接:​​https:

9种改进软件开发过程的策略_wot技术大会的博客-多极客编程

你想知道如何加快软件开发项目的速度吗?通过本文了解如何加快流程和创造高质量产品的策略。在今天的市场中,你是否希望击败你的竞争对手赢得竞争? 最终的解决方案将是快速地软件开发。无论你的公司大小,拥有快速的软件开发将始终让你在竞争中处于领先地位。关于快速开发,你永远不要在软件质量上妥协。这将对公司的发展构成很大的威胁。软件开发涉及的过程是漫长而无止境的。即使已经拥有成熟的市场,也需要适当和持续的改进和

#yyds干货盘点#sql 子查询_文本、的博客-多极客编程

子查询也叫复杂查询,为什么子查询叫做复杂查询呢?因为子查询相当于查询嵌套查询,因为嵌套导致复杂度几乎可以被无限放大(无限嵌套),因此叫复杂查询。下面是一个最简单的子查询例子:SELECT pv FROM ( SELECT pv FROM test)上面的例子等价于 ​​SELECT pv FROM test​​,但因为把表的位置替换成了一个新查询,所以摇身一变成为了复杂查询!所以复杂查询不一定真

关于面向对象设计的一些理解和思路_liatsce的书架的博客-多极客编程

本文中会介绍一些笔者对于面向对象设计概念学习的笔记、理解以及实现思路。希望这些内容能够帮助大家对面向对象设计这一概念有更多的认识。若文中有错误的理解和概念,请大家及时纠正;吸纳大家的建议,对于我来说也是很重要的学习过程之一。 1.基本概念 由于对象是对事物的理解和抽象,所以对象就是对一个事物的属性和行为的理解和抽象。正是这样的一种关系,面向对象就是对一个事物的属性和行为的理解和抽象的方法。理解对象

实践手册:业务引领的devops持续交付研发体系_永远的朋友的博客-多极客编程

导言:在自己从事产品研发实践和管理的十几年职业生涯里,少部分时间经历的是以瀑布式开发为主导的研发模式;绝大部分时间经历的是以敏捷开发为主导的研发模式;在硬件研发制造的场景下,也经历过以IPD(集成产品开发)为主导的研发模式。其实,各种研发体系的出现和行业实践,都是在解决“如何保障产品交付质量?”“如何提高产品交付速度?”的本质问题。同时,对于研发团队而言,不仅仅是按时保质的交付产品即可,如敏捷开发

前后端分离的好处有哪些?-多极客编程

前后端分离是什么?前后端分离的好处都有哪些?如果两者不分离,会带来什么麻烦事?针对网友关注度非常高的话题,我们今天来大家一一解答。一、什么是前后端分离?前后端分离实质上是前后端代码分离,一般后端人员主要开发API接口数据,前端人员根据API使得其数据能够在前端页面交互展示。在企业运营过程中,一个项目往往是多人或者多职来协作完成的,这就涉及到前端和后端,假如在项目代码没有前后端分离,那么,一旦前后端

系统测试常用测试方法-多极客编程

  系统测试一般采取黑盒测试,系统测试的方法也比较多,其中常用的方法有:多任务测试、临界测试、中断测试、等价划分测试  多任务测试  多任务测试是指在非idle状态下,测试对象处于工作状态时,有新的事件发生,如手机进行通话时有短信进行,手机有电话呼入,这种情况就是“多任务”  Eg:手机项目中,查看短信时,有来电时。。。  备注:  1.多任务是黑盒尤其是嵌入式设备中所必须进行的一项最基本的测试,

软件单元测试及测试用例设计_多测师11的博客-多极客编程

  单元测试是针对各功能模块的进行测试,进行充分的单元测试,是提高软件质量,降低研发成本的必由之路。文章对软件测试和单元测试相关概念做了简要说明,以用户注册模块出生年月日的检验为例,说明了用例设计的过程。  1.软件测试  软件测试是指利用相关测试工具,按照一定的测试方案和流程对软件系统的功能和性能进行测试,对可能出现的问题进行分析、评估,发现开发错误并跟踪,以确保所开发的软件满足用户需求。软件测

如何编写测试用例_多测师11的博客-多极客编程

  测试用例:指导性执行测试,帮助证明软件功能或发现软件缺陷的一种说明。每一个测试点的数据设计和步骤设计。  测试用例的重要性:  (1)、便于测试计划的实施  一般主要适用于集成测试、系统测试、回归测试。根据用例知道自己的进度  (2)、规划测试数据的准备  比如注册,要提前准备好手机号、身份证号、不重复的用户名,邮箱等  (3)、编写测试脚本的根本  自动测试的中心任务是编写测试脚本。测试脚本

实践 devops 时,可能面临的六大挑战_wx6112268909e6a的博客-多极客编程

DevOps 是将人员和部门聚集在一起,专注于创建一个统一的系统,将开发和运营的任务和目标结合起来。随着越来越多公司采用 DevOps 流程,实践过程中遇到的各种问题也逐渐浮出水面。因此,任何一家要实践 DevOps 的公司,都应该关注这六个领域,以此来减少各种不利因素对软件开发和部署周期的影响。 1. 没有正确的文化理念 DevOps 文化是关于开发人员和运营人员之间的共同理解,以及对他们构建的