Spring Security 基础:快速搭建安全认证系统

代码温度计
2025-06-15 10:49
阅读 796

开篇:Spring Security 是什么,用来做什么?

开篇:Spring Security 是什么,用来做什么?

在现代的 Web 开发中,安全性是不可或缺的一部分。无论是网站还是后台服务,我们都需要对用户进行身份验证(登录)和权限控制(谁可以看什么、做什么)。Spring Security 就是为了解决这个问题而生的一个框架。

你可以把它想象成一个“门卫”——它能检查每一个访问你应用的人是否合法,是否有资格进入某个页面或执行某项操作。

为什么选择 Spring Security?

  • 它是专门为 Spring 应用量身打造的安全框架。
  • 提供了丰富的功能,包括:登录认证、权限控制、防止常见攻击(如 CSRF)等。
  • 高度可配置,既适用于简单的项目,也适合复杂的企业级系统。

在这篇文章中,我们将从零开始,教你如何用 Spring Security 快速搭建一个最基础的安全认证系统。无需任何前置知识,只要你会写 Java 并运行过 Spring Boot 项目,就能轻松上手!


环境准备:搭建开发环境

环境准备:搭建开发环境

所需工具:

工具 版本建议 备注
JDK 17 或更高版本 Java 开发工具包
Maven 3.8.x 构建工具
IntelliJ IDEA / VS Code / Eclipse 最新版 IDE 工具
Spring Boot 3.x 系列 我们将使用 Spring Initializr 来创建项目

第一步:创建 Spring Boot 项目

访问 https://start.spring.io

选择以下配置:

  • Project: Maven
  • Language: Java
  • Spring Boot Version: 3.x (例如:3.1.0)
  • Dependencies:
    • Spring Web
    • Spring Security

点击【Generate】按钮下载项目压缩包,并解压导入你的 IDE 中。

第二步:运行项目

导入后,找到带有 @SpringBootApplication 注解的类,运行它。如果看到类似如下日志:

Tomcat started on port(s): 8080 (http)

说明你的项目已经成功启动!现在我们可以开始集成 Spring Security 了。


核心概念:Spring Security 的三大关键词

核心概念:Spring Security 的三大关键词

要理解 Spring Security,你需要知道三个核心概念:

1. 用户认证(Authentication)

就是确认你是谁。比如你在网站登录时输入用户名和密码,系统就会去验证这些信息是否正确。

类比:
相当于你要进小区大门,保安问你:“你是哪栋楼的?”你说:“我是3号楼的”,然后出示身份证。

2. 权限控制(Authorization)

就是确认你能干什么。不同用户有不同的权限。比如普通员工不能查看财务数据,管理员才可以。

类比:
你进入小区之后,想去物业办公室,但只有物业人员才能进去,这时候门禁就检查你的身份是否有权限开门。

3. 安全配置(Security Configuration)

Spring Security 的配置类就像是一份“安检手册”,告诉系统哪些人可以访问哪些内容,登录失败怎么处理等。

类比:
这就好比是你给保安写的守则:“所有外来人员必须登记”,“访客只能待在大厅”,等等。


实战项目:一步步搭建安全认证系统

我们将构建一个包含以下功能的简单系统:

  1. 所有请求都必须登录
  2. 支持内存中存储两个用户:user 和 admin
  3. 区分角色权限:user 只能访问 /hello,admin 可以访问 /admin

✅ 本项目基于 Spring Boot + Spring Security 3.x,请确保你的项目引入了 Spring Security 依赖。


步骤一:配置安全设置(SecurityConfig 类)

创建一个类 SecurityConfig.java,并输入以下代码:

package com.example.demo.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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public InMemoryUserDetailsManager userDetailsService(PasswordEncoder encoder) {
        UserDetails user = User.builder()
                .username("user")
                .password(encoder.encode("user123"))
                .roles("USER")
                .build();

        UserDetails admin = User.builder()
                .username("admin")
                .password(encoder.encode("admin123"))
                .roles("ADMIN")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/admin").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(login -> login
                .defaultSuccessUrl("/hello", true)
            )
            .logout(logout -> logout
                .logoutSuccessUrl("/login")
            );
        return http.build();
    }
}

这段代码做了几件事:

API接口文档-2

  1. 定义了一个密码编码器 BCryptPasswordEncoder,用于加密用户密码;
  2. 创建了两个内置用户:useradmin
  3. 设置访问规则:
    • 访问 /admin 页面,必须是 ROLE_ADMIN 角色;
    • 其他页面只要登录即可访问;
  4. 使用默认的登录页进行认证;
  5. 登出时跳转到登录页面。

⚠️ 注意:Spring Security 从 3.0 开始,默认使用 Servlet API,所以不需要额外启用其他模块。


步骤二:添加控制器(Controller)

接下来我们添加一个控制器来测试不同用户的访问权限。

新建文件 HelloController.java

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "你好,欢迎来到主页!";
    }

    @GetMapping("/admin")
    public String admin() {
        return "这里是管理员专区。";
    }
}

这个控制器有两个接口:

  • /hello:任何人都可以通过登录后访问;
  • /admin:必须是 admin 用户才能访问。

步骤三:测试访问

重启项目,访问以下地址试试:

测试地址:

  • http://localhost:8080/hello —— 会跳转到登录页;
  • 登录账号:
    • 用户名:user,密码:user123
    • 用户名:admin,密码:admin123

尝试分别用 user 和 admin 登录:

  • 登录成功后都会跳转到 /hello 页面;
  • 如果访问 /admin
    • user 账号会报错 403(无权限);
    • admin 账号可以正常访问;

恭喜你!你已经完成了第一个 Spring Security 安全系统的搭建!


进阶一点的内容:自定义登录页(Optional)

如果你不满意默认的登录页面,可以自定义一个 HTML 页面。

步骤一:创建登录页面

resources/templates/ 目录下创建文件 login.html,内容如下:

<!DOCTYPE html>
<html>
<head>
    <title>登录</title>
</head>
<body>
    <h2>请登录</h2>
    <form action="/login" method="post">
        <div>
            <label>用户名:<input type="text" name="username"></label>
        </div>
        <div>
            <label>密码:<input type="password" name="password"></label>
        </div>
        <button type="submit">登录</button>
    </form>
</body>
</html>

步骤二:修改配置类

回到 SecurityConfig.java,修改 securityFilterChain() 方法:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/admin").hasRole("ADMIN")
            .anyRequest().authenticated()
        )
        .formLogin(login -> login
            .loginPage("/login")     // 指定自定义登录页
            .permitAll()             // 允许所有人都能访问登录页
        )
        .logout(logout -> logout
            .logoutSuccessUrl("/login")
        );
    return http.build();
}

数据库设计模型-1

还要添加一个控制器来渲染登录页面:

@GetMapping("/login")
public String showLoginPage() {
    return "login"; // 返回模板名称,注意模板放在 templates 文件夹中
}

这样你就有了属于自己的登录界面啦!


新手常见问题解答(FAQ)

Q1:为什么我登录失败?

可能是用户名或密码不正确,请核对输入的信息是否与你在 userDetailsService 中设置的一致。

还可以检查是否启用了登录端点,有没有被误拦截。


Q2:登录成功后一直跳回登录页?

可能的原因:

  • defaultSuccessUrl("/hello", true) 中参数含义是登录成功后强制跳转到指定地址;
  • 请确认路径是否正确;
  • 检查控制器中是否存在路径冲突或未授权的问题;
  • 清除浏览器缓存再试一次。

Q3:如何退出登录?

发送 GET 请求到 /logout 地址即可退出,你可以添加一个链接或者按钮:

<a href="/logout">登出</a>

记得在配置中开启注销支持(已默认开启)。


Q4:忘记加 PasswordEncoder 会怎样?

如果不加,你会遇到登录失败的问题,因为 Spring Security 默认要求密码是经过加密存储的。


Q5:我能不能用数据库做用户管理?

当然可以!本文只是演示了内存用户管理器。实际开发中更推荐使用数据库进行持久化用户管理(比如用 JPA 存储用户信息),这部分我们将在下一篇文章讲解。


学习建议:下一步该学什么?

恭喜你学会了 Spring Security 的基础使用方法!接下来你可以在以下几个方向继续深入学习:

🧩 推荐学习路径:

  1. 学会使用数据库管理用户

    • 教程主题:如何连接 MySQL 数据库进行用户认证;
    • 框架参考:JPA / MyBatis / JDBC;
  2. 理解 OAuth2 和 JWT

    • 教程主题:前后端分离下的 token 认证方式;
    • 适合场景:移动端、RESTful API 服务;
  3. 掌握多种认证方式

    • 如 LDAP 认证、短信验证码、二维码扫码登录等;
  4. 安全加固专题

    • 防止 CSRF、XSS、SQL 注入等攻击;
    • 加密策略、日志审计等内容;
  5. 实战完整项目

    • 做一个小商城后台管理系统,练习权限分级、菜单控制等高级玩法;
    • 综合使用 Spring Security + Vue / React 前端;

总结

通过这篇文章,我们一步一步地搭建了一个简单但完整的 Spring Security 安全认证系统,实现了:

✅ 用户登录
✅ 内存用户管理
✅ 角色权限控制
✅ 自定义登录页面

尽管我们只用到了 Spring Security 很少一部分功能,但这已经足够让你打开安全世界的大门。

记住一句话:安全不是附加功能,而是整个系统架构的基础。

希望你继续探索下去,在未来的项目中把 Spring Security 用得游刃有余!


📌 附录:本文示例源码结构建议

src/
├── main/
│   ├── java/
│   │   └── com.example.demo/
│   │       ├── config/SecurityConfig.java
│   │       ├── controller/HelloController.java
│   ├── resources/
│   │   ├── templates/login.html
│   │   └── application.properties (保持默认即可)

如果你按照这个结构编写,应该可以顺利跑起来哦!


如有疑问,欢迎留言交流~

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝