Spring Security 起步

1. 前言

上一节我们介绍了「Spring Security」的诞生与应用,本节将创建一个最基本的 Spring Security 应用,以便理解 Spring Security 的运行机制。

本节实例是在 Servlet 应用中集成 Spring Security 安全框架,在标准的 Servlet 过滤器(Filter)中应用 Spring Security 安全机制。

基本环境说明

  • Jdk 8
  • Maven
  • Spring Boot
  • Spring Security 5.3.2

2. 实例详解

2.1 项目的目录结构

本实例我们一共需要创建两个文件,其一是 maven 的工程描述文件 pom.xml 我们把它放在工程的根目录下;其二是 Spring Boot 项目的启动文件 HelloSecurityApplication.java

完整的目录描述如下:

├── pom.xml
├── src/
    └── main/
       └──java/
          └──imooc/
             └──springsecurity/
                └──HelloSecurityApplication.java

2.2 增加 Spring Security 依赖

首先,我们要将 Spring Boot 环境配置到工程中,也就是在 pom.xml 文件中将当前工程的父级依赖指定为 Spring Boot。

此步写法如下,在 pom.xml 文件中增加以下节点信息:

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.3.0.RELEASE</version>
  <relativePath/>
</parent>

第二步,在配置好父级依赖后,继续在 pom.xml 中增加 Spring Security 依赖「spring-boot-starter-security」。

此步写法如下:

<dependencies>
    <!-- 重点依赖 -->
    <dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-security</artifactId>
	</dependency>

</dependencies>

第三步,为了让本实例的效果看得见,我们要将它设置成 Web 工程,所以我们需要继续在 pom.xml 文件中添加依赖。

此步写法如下:

<dependencies>
	...

    <!-- 用于展示认证效果 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
</dependencies>

2.3 增加启动类

src/main/java 中创建类 HelloSecurityApplication.java,并设置包名(本项目包名为:imooc.springsecurity),之后在该类中增加 Spring Boot 启动声明。

package imooc.springsecurity;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class HelloSecurityApplication {

	public static void main(String[] args) {
		SpringApplication.run(HelloSecurityApplication.class, args);
	}

    /**
     * 此方法用于演示测试结果。
     */
    @RequestMapping("/hello")
    private String sayHello() {
        return "{'msg': 'hi'}";
    }

}

到此为止,我们的「Spring Security」项目就搭建完成了。

2.4 运行测试

为了避免不同开发环境的干扰,我们统一使用 Maven 命令行的方式编译和执行项目。

打开控制台,在 pom.xml 同级目录(工程根目录)中输入命令 mvn spring-boot:run 来启动 Spring Boot 。

此步执行命令如下:

mvn spring-boot:run

访问 http://localhost:8080/hello 可以看到如下页面,此时系统要求我们输入用户名密码完成身份认证。

图片描述

身份认证

Spring Security 项目在默认配置下,会自动生成一个名为「user」的用户,并分配其随机密码,此密码可以从控制台的日志信息中找到:

...
Using generated security password: 8e557245-73e2-4286-969a-ff57fe326336
...

填入用户名密码,点击登录,将看到认证结果页:

图片描述

认证结果
此时,我们完成了第一个「Spring Security」实例。

3. Spring Boot 的默认配置项

在刚刚的实例中,我们并没有做任何关于安全性的配置,但是应用系统以及自带了访问控制,并且生成了一个测试用户,这是怎么做到的呢?答案就在 Spring Security 的默认配置中。

在 Spring Boot 方式下启动 Spring Security 工程,将会自动开启如下配置项:

  • 默认开启一系列基于 springSecurityFilterChain 的 Servlet 过滤器,包含了几乎所有的安全功能,例如:保护系统 URL、验证用户名、密码表单、重定向到登录界面等;
  • 创建 UserDetailsService 实例,并生成随机密码,用于获取登录用户的信息详情;
  • 将安全过滤器应用到每一个请求上。

除此之外,Spring Security 还有一些其他可配置的功能:

  • 限制所有访问必须首先通过认证;
  • 生成默认登录表单;
  • 创建用户名为「user」的可以通过表单认证的用户,并为其初始化密码;
  • 使用 BCrypt 方式加密密码;
  • 提供登出的能力;
  • 保护系统不受 CSRF 攻击;
  • 会话固定保护;
  • 集成安全消息头;
  • 提供一些默认的 Servlet 接口,如:「getRemoteUser」、「getUserPrincipal」、「isUserInRole」、「login」和「logout」。

以上内容我们将在后续的章节中陆续向大家介绍。

4. 小结

图片描述

流程小结
本节作为 Spring Security 的起点,展示了如何在 Spring Boot 项目中集成 Spring Security 功能。Spring Security 默认情况下会打开用户的表单认证功能,并创建用户名为「user」的测试用户,其密码在系统启动时生成,可在系统启动日志中找到。

下一节,我们将讨论 Spring Security 的安全架构,了解其设计思路。