本书所有的示例都基于Inellij IDEA 创建的Spring Boot项目,因此读者需要具备一定的Spring相关知识。
1.1 Spring Security简介Spring Security 的前身是Acegi Security, 在被收纳为Spring 子项目后正式更名为SpringSecurity.
在笔者成书时,Spring Security已经升级到5.1.3.RELEASE版本,加入了原生OAuth2.0框 架,支持更加现代化的密码加密方式。可以预见,在Java应用安全领域,Spring Security 会成为被首先推崇的解决方案,就像我们看到服务器就会联想到Linux一样顺理成章。
应用程序的安全性通常体现在两个方面:认证和授权。
认证是确认某主体在某系统中是否合法、可用的过程。这里的主体既可以是登录系统的用户,也可以是接入的设备或者其他系统。
授权是指当主体通过认证之后,是否允许其执行某项操作的过程。
这些概念并非Spring Security 独有,而是应用安全的基本关注点。Spring Security可以帮助我们更便捷地完成认证和授权。
Spring Security 支持广泛的认证技术,这些认证技术大多由第三方或相关标准组织开发。 Spring Seurity已经集成的认证技术如下:
◎ HTTP BASIC authentication headers: 一个基于IETF RFC的标准。
◎ HTTP Digest authentication headers:一 个基于IETF RFC的标准。
◎ HTTP Xx.509 client cerificate exchange: 一个基于IETP RFC的标准。
◎LDAP:一种常见的跨平台身份验证方式。
◎Form-based authentication:用于简单的用户界面需求。
◎OpenID authentication:一种去中心化的身份认证方式。
◎Authentication based on pre-established request headers:类似于Computer AssociatesSiteMinder,一种用户身份验证及授权的集中式安全基础方案。
◎Jasig Central Authentication Service:单点登录方案。
◎Transparent authentication context propagation for Remote Method Invocation (RM) and
HttpInvoker:一个Spring远程调用协议。
Automatic "remember me" authentication:允许在指定到期时间前自行重新登录系统。 Anonymous authentication:允许匿名用户使用特定的身份安全访问资源。
◎ Run-as authentication: 允许在一个会话中变换用户身份的机制。
◎Java Authentication and Authorization Service: JAAS,Java 验证和授权API。
◎Java EE container authentication:允许系统继续使用容器管理这种身份验证方式。
◎Kerberos:一种使用对称密钥机制,允许客户端与服务器相互确认身份的认证协议。 除此之外,Spring Security 还引入了一些第三方包,用于支持更多的认证技术,如JOSSO 等。如果所有这些技术都无法满足需求,则Spring Security允许我们编写自己的认证技术。因 此,在绝大部分情况下,当我们有Java应用安全方面的需求时,选择Spring Security往往是正确而有效的。
Internet 工程任务组(Internet Engineering Task Force, IETF) 是推动Internet标准规范制定 的最主要的组织。请求注解( Request For Comments, RFC)包含大多数关于Internet 的重要文字资料,被称为“网络知识圣经”。
在授权上,Spring Security不仅支持基于URL对Web的请求授权,还支持方法访问授权、对象访问授权等,基本涵盖常见的大部分授权场景。
很多时候,一个系统的安全性完全取决于系统开发人员的安全意识。例如,在我们从未听过SQL注入时,如何意识到要对SQL注入做防护?关于Web系统安全的攻击方式非常多,诸 如XSS、CSRF 等,未来还会暴露出更多的攻击方式,我们只有在充分了解其攻击原理后,才 能提出完善而有效的防护策略。在笔者看来,学习Spring Security并非局限于降低Java应用的
4 | Spring Security实战
安全开发成本,通过Spring Security了解常见的安全攻击手段以及对应的防护方法也尤为重要,这些是脱离具体开发语言而存在的。
1.2 创建一个简单的Spring Security项目本节创建一个简单的Spring Security项目,带领大家初步领略Spring Security带来的便利。下面我们就完整地“走”一遍创建项目的流程。
通过Itellj IDEA创建Spring Boot项目的方式有许多种,其中最简单的方式就是使用Spring Initializr工具,省略了在http://start.spring.io.中生成并导入Inellij IDEA的过程。Eclipse 也提供 了一个可以实现类似功能的插件: STS (Spring Tool Suite),感兴趣的读者可以自行了解。此.处我们单击“Next”按钮进入下一个页面,如图1-1所示。
在图1-2所示页面中,除可以设置项目的Group. Artifact 这些基本信息外,还有其他几个 配置可选。例如,对于Type属性,可以选择Maven Project或者Gradle Project作为项目管理工具;对于Language属性,可以选择使用Java、Kotin或Groovy作为开发语言。
Spring Initializr 将根据我们的选择自动构建项目骨架,选好之后单击“Next"按钮进入下一个页面,如图1-3所示。
Spring Initializr 允许我们提前选定一些常用的项目依赖,此处我们选择Security 作为构建 Spring Security项目的最小依赖,选择Web作为Spring Boot构建Web应用的核心依赖。
当项目创建完成后,可以得到如图1-4所示的目录结构。
6 | Spring Security实战
打开pom.xml文件,看看Spring Initializr引入了哪些依赖。
从代码中可以看到,在选择Security之后,Spring Initalizr 自动引入spring scurity-web和 spring-security-config两个核心模块,这正是官方建议引入的Spring Security 最小依赖。当需要 引入更多的Spring Security 特征时,再编辑pom.xml文件即可。如果不通过Spring Initializr 添 加Spring Security的相关依赖,则手动将依赖信息添加到pom.xml文件也是可以的。
同理,通过Gradle管理的项目只需引入spring-security-web和spring- security-config两个核
心模块。
下面打开程序的入口类SpnDnpDppcaioin声明一个hello 路由 8 |Spring Security实战
首先选中SpringDemoApplication 类并单击运行项(如果没有出现运行项,则可能是因为 Maven没有初始化。选中pom.xml,单击右键,从右键快捷菜单中选择Add as maven build file选项,重新构建即可)。在默认情况下,项目将成功启动并监听8080端口。如果运行失败,则可能是因为8080端口被占用。
接着打开浏览器访问localhost:8080, 浏览器将弹出一个需要进行身份验证的对话框,如图1-5所示。
在引入Spring Security 项目之后,虽然没有进行任何相关的配置或编码,但Spring Scrtry有一个默认的运行状态,要求在经过HTTP基本认证后才能访问对应的URL资源,其默认使用 的用户名为user,密码则是动态生成并打印到控制台的串随机码。 翻看控制台的打印信息, 可以看到如图1-6 所示的输出。
输入用户名和密码后,单击“登录”按钮即可成功访问hello页面,如图1-7所示。
当然,右HTTP基本认证中,用户名和密码都是可以配置的,最常见的就是在resources下的配置文件中修改,如图1-8所示。
打开application properties,输入以下配置信息:
重新启动程序,发现控制台不再打印默认密码串了,此时使用我们自定义的用户名和密码即可登录。
事实上,绝大部分Web应用都不会选择HTTP基本认证这种认证方式,除安全性差、无法携带cookie等因素外,灵活性不足也是它的一个主要缺点。通常大家更愿意选择表单认证,自己实现表单登录页和验证逻辑,从而提高安全性。



