ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Spring Security 初识:从零创建第一个受保护的应用

Spring Security 初识:从零创建第一个受保护的应用 1. 引言在 Web 应用开发中安全永远是绕不开的话题。无论是用户登录、权限控制还是接口防刷安全框架都扮演着至关重要的角色。而在 Java 生态中Spring Security无疑是最主流、最强大的安全解决方案。很多初学者第一次接触 Spring Security 时往往会被它庞大的过滤器链、复杂的配置类和各种安全概念劝退。但事实上Spring Security 的设计哲学是约定大于配置——你甚至不需要写一行安全相关的代码它就能为你的应用提供基础的保护。本文将通过一个最简单的实战项目带你迈出 Spring Security 的第一步创建一个包含安全依赖的 Spring Boot 应用启动它观察默认的登录页和自动生成的密码并理解背后默认安全过滤器链的工作原理。2. 环境准备在开始之前请确保你的本地环境满足以下条件JDK8 或以上版本推荐 11 或 17构建工具Maven 3.6 或 Gradle本文以 Maven 为例IDEIntelliJ IDEA、Eclipse 或 VS Code 均可网络能够访问 Spring Initializr 或 Maven 中央仓库本文使用的 Spring Boot 版本为2.7.x稳定版。如果你使用 Spring Boot 3.x核心概念完全一致仅部分配置项名称略有差异。3. 创建项目3.1 使用 Spring Initializr 创建项目打开 Spring Initializr按照以下步骤配置项目Project选择MavenLanguage选择JavaSpring Boot选择2.7.18或你本地的稳定版本Group填写com.exampleArtifact填写security-demoDependencies搜索并添加以下依赖Spring Web用于构建 Web 应用Spring Security核心安全依赖点击Generate按钮下载项目压缩包解压后用 IDE 打开。3.2 项目结构一览生成的项目结构如下security-demo/ ├── src/ │ └── main/ │ ├── java/ │ │ └── com/example/securitydemo/ │ │ └── SecurityDemoApplication.java │ └── resources/ │ └── application.properties ├── pom.xml └── ...其中pom.xml中已经自动引入了我们需要的两个核心依赖dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependency4. 编写第一个受保护的接口为了让应用有东西可以被保护我们先创建一个简单的 REST 接口。在com.example.securitydemo包下新建一个控制器类HelloController.javapackagecom.example.securitydemo;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;RestControllerpublicclassHelloController{GetMapping(/hello)publicStringhello(){returnHello, Spring Security!;}}这个接口非常简单访问/hello会返回一段欢迎文字。但当我们引入 Spring Security 依赖后这个接口将不再是裸奔状态——所有请求都会被默认的安全机制拦截。5. 启动应用观察默认安全行为5.1 启动应用直接运行SecurityDemoApplication的主方法或者使用 Maven 命令启动mvn spring-boot:run观察控制台输出你会看到类似如下的日志Using generated security password: 8a3f9c2e-1b4d-4e7f-9a2c-5d6e7f8a9b0c Using generated security password: 8a3f9c2e-1b4d-4e7f-9a2c-5d6e7f8a9b0c这一行就是 Spring Security 自动生成的默认密码用户名固定为user。请务必复制保存这串密码稍后登录时会用到。5.2 访问受保护接口打开浏览器访问http://localhost:8080/hello。你会发现页面并没有直接显示Hello, Spring Security!而是被重定向到了一个登录页面http://localhost:8080/login这就是 Spring Security 的默认登录页。它由框架自动生成包含用户名和密码两个输入框。5.3 使用默认账号登录在登录页中输入用户名user密码控制台输出的那串随机密码点击Sign in页面会跳转回/hello并成功显示Hello, Spring Security!至此你已经成功创建了第一个受 Spring Security 保护的应用6. 核心理解约定大于配置整个过程我们没有编写任何安全配置代码但应用却自动获得了登录认证能力。这正是 Spring Security 的约定大于配置理念的体现。当我们引入spring-boot-starter-security依赖后Spring Boot 的自动配置机制会为我们做以下几件事自动生成一个默认用户用户名为user密码为启动时随机生成的一串 UUID。自动启用表单登录所有请求默认都需要认证后才能访问。自动生成登录页和登出功能/login和/logout端点由框架内置。自动配置安全响应头如X-Content-Type-Options、Cache-Control等防止常见 Web 攻击。这些默认行为都定义在SpringBootWebSecurityConfiguration中。如果你不提供任何自定义的SecurityFilterChainBean框架就会使用这套默认配置。7. 核心理解默认的安全过滤器链Spring Security 的核心机制是过滤器链Security Filter Chain。当请求进入应用时会依次经过一系列过滤器每个过滤器负责一项安全检查。默认的过滤器链大致如下否是HTTP 请求SecurityContextPersistenceFilterCsrfFilterUsernamePasswordAuthenticationFilter是否已认证?重定向到 /loginAuthorizationFilter放行到 Controller各过滤器的主要职责如下过滤器职责SecurityContextPersistenceFilter在请求开始时从 Session 加载安全上下文结束时保存回 SessionCsrfFilter处理 CSRF 防护默认拦截非 GET 请求UsernamePasswordAuthenticationFilter处理表单登录请求校验用户名和密码AuthorizationFilter基于当前认证信息做最终的授权判断当未登录用户访问/hello时AuthorizationFilter发现当前没有认证信息于是抛出AccessDeniedException随后框架将请求重定向到/login登录页。登录成功后框架会生成一个Authentication对象存入 Session后续请求便不再被拦截。8. 验证默认配置查看自动生成的登录页Spring Security 的默认登录页虽然功能完整但样式非常朴素。它由DefaultLoginPageGeneratingFilter动态生成 HTML 页面。如果你想确认登录页确实是框架自动生成的可以查看页面源码。你会发现表单的提交地址是/login用户名输入框的name属性为username密码输入框的name属性为password。这些约定都是框架内置的后续自定义登录页时也需要遵循同样的命名规范。9. 小结与下一步通过本文的实践你已经完成了 Spring Security 的入门第一步使用 Spring Initializr 创建了包含安全依赖的项目启动应用并观察到了自动生成的登录页和默认密码使用user和随机密码成功登录理解了约定大于配置的设计理念初步认识了默认安全过滤器链的工作流程Spring Security 的世界远不止于此。下一步你可以尝试在application.properties中配置固定的用户名和密码自定义登录页和登录成功后的跳转逻辑基于内存或数据库实现用户管理使用 JWT 实现无状态认证希望这篇文章能帮你迈出 Spring Security 学习的第一步。如果你在实践过程中遇到任何问题欢迎在评论区留言交流
返回列表