Spring Security上手指南:30分钟搭建认证系统

♀黄杰
2025-12-22 14:24
阅读 1284

大家好,我是你们的老朋友,一个在大厂搬砖三年、业余时间在B站分享技术的Java后端开发者。今天我想和大家聊聊 Spring Security

为什么写这篇教程?因为我在带实习生和回答粉丝私信时,发现很多人一听到“安全框架”就望而却步,觉得高深莫测。其实我当初学的时候也是一头雾水——配置一堆类、注解满天飞,连最基本的登录都搞不定。但后来我发现,只要抓住核心流程,Spring Security并没有那么难

更关键的是,现在几乎每个企业级Java项目(尤其是涉及用户、权限、运营后台的系统)都离不开它。哪怕你主要用Python写数据分析脚本,一旦你的工具需要对外提供Web服务(比如给运营团队做一个内部管理系统),你就得考虑安全性。所以,掌握Spring Security,是迈向专业后端开发的重要一步。

这篇文章专为零基础小白设计,我会用最直白的语言、最简短的代码,带你快速跑通一个完整的认证流程。准备好了吗?我们开始!


一、Spring Security到底是什么?

简单说,Spring Security 是一个用于保护Java应用的安全框架。它能帮你做两件事:

  1. 认证(Authentication):你是谁?比如用户名密码登录。
  2. 授权(Authorization):你能做什么?比如普通用户只能看自己的数据,管理员可以删用户。

你可以把它想象成小区的门禁系统:

  • 保安(Security)先检查你的门禁卡(认证)
  • 然后根据你的业主身份(角色),决定你能不能进健身房、地下车库(授权)

💡 小知识:虽然标题提到了Python,但Spring Security是Java生态的工具。不过很多团队会用Python写数据处理/运营工具,而用Java写主业务系统。两者常配合使用。比如:Python脚本处理完数据后,通过API推给Java系统,这时Java端就需要Spring Security来保护这些API不被乱调。


二、环境准备:5分钟搭好开发环境

所需工具清单

工具 版本建议 说明
JDK 17 或 21 Spring Boot 3.x 需要 JDK 17+
Maven / Gradle 最新版 项目构建工具
IDE IntelliJ IDEA(推荐)或 VS Code 写代码用
浏览器 Chrome / Edge 测试登录页面

创建项目

最简单的方式是用 Spring Initializr 在线生成项目。

  1. 打开网站,选择:

    • Project: Maven
    • Language: Java
    • Spring Boot: 3.2.x(最新稳定版)
    • Project Metadata 填你的信息(如 Group: com.example, Artifact: security-demo
  2. Dependencies 搜索框中添加:

    • Spring Web
    • Spring Security
  3. 点击 Generate 下载 ZIP 包,解压后用IDE打开。

✅ 验证:项目导入后,你应该能看到 pom.xml 中包含 spring-boot-starter-security 依赖。


三、核心概念:3个关键词讲清楚

很多教程一上来就讲 AuthenticationManagerUserDetailsService,新手直接懵了。其实你只需要先理解这三个东西:

1. 用户(User)

系统里的一个账号,有用户名、密码、角色(比如 USER、ADMIN)。

2. 密码编码器(PasswordEncoder)

绝对不要存明文密码! Spring Security 要求密码必须加密存储。最常用的是 BCryptPasswordEncoder,它每次加密结果都不一样(防彩虹表攻击)。

3. 安全配置(SecurityConfig)

这是一个用 @Configuration 标记的类,告诉Spring Security:

  • 哪些路径需要登录?
  • 哪些路径公开访问?
  • 用什么方式登录?(表单 / JSON / OAuth2...)

四、实战项目:从零搭建一个带登录的系统

我们将完成一个极简但完整的项目:
✅ 访问 /public 不用登录
✅ 访问 /admin 必须用 admin 账号登录

第一步:写一个测试接口

src/main/java/com/example/securitydemo 下新建 HomeController.java

@RestController
public class HomeController {

    @GetMapping("/public")
    public String publicPage() {
        return "这是公开页面,所有人都能看!";
    }

    @GetMapping("/admin")
    public String adminPage() {
        return "欢迎来到管理员后台!";
    }
}

第二步:配置用户和密码

新建 SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    // 告诉Spring如何验证用户
    @Bean
    public UserDetailsService userDetailsService() {
        // 创建两个用户:user(普通用户)和 admin(管理员)
        UserDetails user = User.builder()
                .username("user")
                .password(passwordEncoder().encode("123456")) // 密码必须加密!
                .roles("USER")
                .build();

        UserDetails admin = User.builder()
                .username("admin")
                .password(passwordEncoder().encode("admin123"))
                .roles("ADMIN", "USER") // admin 同时拥有两个角色
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    // 密码编码器:必须提供!
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 安全规则配置
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public").permitAll()      // 公开访问
                .requestMatchers("/admin").hasRole("ADMIN")  // 需要 ADMIN 角色
                .anyRequest().authenticated()                // 其他所有请求都要登录
            )
            .formLogin(form -> form                        // 启用表单登录
                .loginPage("/login")                       // 自定义登录页(可选)
                .permitAll()                               // 登录页本身要公开
            )
            .logout(logout -> logout.permitAll());         // 登出也要公开

        return http.build();
    }
}

🔍 代码解读:

  • InMemoryUserDetailsManager:把用户存在内存里(适合演示,生产要用数据库)
  • .hasRole("ADMIN"):注意这里写的是 ADMIN,但实际存储的角色名是 ROLE_ADMIN(Spring自动加前缀)
  • 表单登录是默认开启的,如果不自定义页面,Spring会给你一个超简陋的登录页

第三步:启动并测试

  1. 运行 SecurityDemoApplication.main()
  2. 打开浏览器访问:
    • http://localhost:8080/public → 直接看到内容 ✅
    • http://localhost:8080/admin → 自动跳转到登录页
  3. 输入用户名 admin,密码 admin123 → 成功进入管理页 ✅
  4. 尝试用 user / 123456 登录 → 访问 /admin 会被拒绝 ❌

🎉 恭喜!你已经完成了第一个Spring Security项目!


五、常见问题:新手最容易踩的坑

Q1:为什么登录后还是跳回登录页?

原因:CSRF(跨站请求伪造)保护默认开启,但你的登录请求没带 _csrf token。

解决方案(任选其一):

  • 在登录页的 <form> 中加入 <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
  • 或者临时关闭 CSRF(仅开发环境!):
    http.csrf(csrf -> csrf.disable());
    

⚠️ 注意:生产环境千万别关 CSRF!

Q2:密码明明对,却提示“Bad credentials”

原因:密码没有用 PasswordEncoder 加密,或者用了不同的编码器。

检查点

  • 是否在 userDetailsService() 中调用了 passwordEncoder().encode()
  • 是否提供了 PasswordEncoder@Bean

Q3:如何自定义登录成功/失败的跳转?

formLogin 中配置:

.formLogin(form -> form
    .successForwardUrl("/home")     // 登录成功跳转
    .failureForwardUrl("/login?error") // 失败跳转
)

Q4:我的项目用JSON交互(前后端分离),怎么处理?

关闭表单登录,改用 httpBasic 或自定义过滤器:

.httpBasic(withDefaults()) // 启用 HTTP Basic 认证(适合API)
// 或者完全自己实现登录逻辑(后续进阶内容)

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

你现在掌握了Spring Security的基础骨架。但真实项目远比这复杂。我建议按以下路径深入:

1️⃣ 数据库存储用户(别再用内存了!)

  • 学习 JdbcUserDetailsManager 或自定义 UserDetailsService
  • 把用户、角色、权限存在 MySQL / PostgreSQL 中

2️⃣ 前后端分离认证方案

  • JWT(JSON Web Token)集成
  • 自定义登录接口返回 token
  • OncePerRequestFilter 验证 token

3️⃣ 细粒度权限控制

  • 方法级权限:@PreAuthorize("hasRole('ADMIN')")
  • 动态权限:从数据库读取用户可访问的URL列表

4️⃣ 与OAuth2整合

  • 接入微信、GitHub、企业微信登录
  • 作为资源服务器保护API

💬 我在B站有一套《Spring Security从入门到放弃》系列(其实是“从入门到精通” 😄),下一期就会讲JWT+Vue3的完整登录流程,欢迎关注!


结语:安全不是功能,而是底线

最后想强调一点:安全不是“加个登录就行”的附加功能,而是系统设计的基石。哪怕你只是给运营团队写一个小工具,只要涉及数据,就必须考虑“谁能看到、谁能修改”。

我见过太多实习生写的内部系统,因为没加认证,导致测试数据被误删、敏感信息泄露。Spring Security 虽然初期有点门槛,但它能让你用最少的代码,获得企业级的安全保障。

希望这篇教程能帮你迈出第一步。记住:所有高手,都是从“Hello World”开始的

有问题欢迎在评论区留言,我会一一解答。下期见!

评论 0

最热最新
暂无评论
♀黄杰Lv.1
0
影响力
0
文章
0
粉丝