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

Prompt造梦师
2025-06-26 10:24
阅读 382

一、开篇:Spring Security是什么?为什么要学它?

一、开篇:Spring Security是什么?为什么要学它?

在开发网站或应用程序时,我们常常需要实现一些基本的权限控制功能,比如:

  • 用户必须登录后才能访问某些页面
  • 管理员用户拥有更多权限
  • 某些接口只能特定角色调用……

而这些功能的核心,就是安全控制。Spring Security,正是 Java 生态中最流行的安全框架之一。

简单来说,Spring Security 就是帮助我们在 Spring Boot(或其他 Spring 项目)中快速添加安全控制的一套工具包

无论你是做一个后台管理系统、电商平台,还是微服务架构下的 API 安全防护,Spring Security 都是你绕不开的一个利器。

这篇文章的目标非常明确:带着你从零开始,快速搭建一个基于 Spring Boot + Spring Security 的基础安全认证系统。


二、环境准备:搭建你的第一个 Spring Security 项目

二、环境准备:搭建你的第一个 Spring Security 项目

1. 开发工具准备

我们需要以下工具:

  • JDK 17 或以上版本(推荐使用 OpenJDK)
  • IDE:IntelliJ IDEA(社区版即可)或 Eclipse(建议新手使用 IDEA)
  • Maven(如果你不熟悉也可以用 Gradle)

2. 创建 Spring Boot 项目

你可以使用 https://start.spring.io 快速生成一个 Spring Boot 工程。

选择如下配置:

  • Project: Maven
  • Language: Java
  • Spring Boot Version: 最新稳定版(如 3.2.x)
  • Dependencies:
    • Spring Web(用于创建 REST API)
    • Spring Security(核心依赖)

点击 "Generate" 下载 zip 文件,并解压到本地文件夹,然后用 IDE 导入即可。

3. 项目结构简介

下载并导入之后,你应该看到类似下面的结构:

my-security-demo/
├── src/
│   └── main/
│       ├── java/
│       │   └── com.example.demosecurity/
│       │       ├── DemoSecurityApplication.java
│       │       └── config/ (稍后我们将放配置类)
│       │
│       └── resources/
│           ├── application.properties
└── pom.xml

现在我们可以正式进入编写代码阶段了!


三、核心概念:5分钟搞懂 Spring Security 的三大关键概念

三、核心概念:5分钟搞懂 Spring Security 的三大关键概念

在写代码之前,先理解几个关键名词,它们会在整个 Spring Security 使用过程中反复出现:

1. Authentication(身份验证)

就是“你是谁”的问题。例如用户输入用户名和密码,系统去数据库查找是否匹配。这个过程叫做身份验证。

2. Authorization(授权)

就是“你能干什么”的问题。例如普通用户不能查看管理界面,管理员可以。这就是授权控制。

3. Filter Chain(过滤链)

这是 Spring Security 内部处理请求的安全机制。每个请求都要经过多个安全检查点(Filter),最终决定能否通过。

💡 举个形象的例子:

如果把整个系统比作一座大楼,那么 Filter Chain 是门口的层层门禁,每个 Filter 就是一道门,只有都通过了,你才能进入房间(访问接口)。

接下来你会更清楚地看到这些概念是如何体现在代码中的。


四、实战项目:一步步带你完成基础安全系统

四、实战项目:一步步带你完成基础安全系统

微服务架构示意图-2

第一步:启动 Spring Boot 项目

运行 DemoSecurityApplication.java 文件的主函数,你会看到控制台输出启动日志。

默认情况下,Spring Security 自动启用了最基本的安全保护。即使你没有写任何配置代码,所有的 HTTP 接口也会被保护起来。

试着打开浏览器访问:http://localhost:8080
你会发现被跳转到了 /login 页面,因为默认开启了登录保护。

但我们现在没有登录账号,所以会一直卡在这里。我们需要自己设置用户名和密码。

第二步:配置默认的内存用户名和密码

修改 application.properties 文件,添加以下内容:

spring.security.user.name=admin
spring.security.user.password=123456

重启项目,再访问 / 或任意路径,会提示登录。

使用 admin / 123456 登录成功后,就可以继续访问资源了。

✅ 这是最简单的“内存中配置用户”方式。

第三步:编写一个安全测试接口

为了测试权限控制,我们来写一个最简单的控制器接口。

com.example.demosecurity 包下新建一个类:TestController.java

package com.example.demosecurity;

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

@RestController
public class TestController {
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, Spring Security!";
    }
}

重启应用,访问:http://localhost:8080/hello
你会看到必须登录才能访问该接口。

第四步:自定义安全配置

现在我们尝试自定义配置,例如开放 /hello 接口无需登录也能访问。

config/ 目录下新建 SecurityConfig.java 文件:

package com.example.demosecurity.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.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/hello").permitAll() // 允许所有人访问 /hello
                .anyRequest().authenticated()          // 其他所有请求都需要认证
            )
            .formLogin(login -> login
                .defaultSuccessUrl("/home", true)      // 成功登录后跳转的首页
            )
            .logout(logout -> logout
                .logoutSuccessUrl("/")                 // 注销后返回首页
            );

        return http.build();
    }
}

这样配置完成后:

  • /hello 可以匿名访问
  • 访问其他路径(比如 /xxx)会被拦截,需要登录

第五步:扩展多个用户(可选)

如果你想模拟多个用户角色,可以在 SecurityConfig.java 中加上如下代码:

@Bean
public UserDetailsService userDetailsService() {
    UserDetails admin = User.withDefaultPasswordEncoder()
        .username("admin")
        .password("123456")
        .roles("ADMIN") // 角色名自动加前缀 ROLE_
        .build();

    UserDetails user = User.withDefaultPasswordEncoder()
        .username("user")
        .password("123456")
        .roles("USER")
        .build();

    return new InMemoryUserDetailsManager(admin, user);
}

⚠️ 注意:withDefaultPasswordEncoder() 仅用于学习演示,不可用于生产环境。生产应使用 BCrypt 加密。

接着你可以对 /admin-page 设置角色访问限制:

.authorizeHttpRequests(auth -> auth
    .requestMatchers("/hello").permitAll()
    .requestMatchers("/admin-page").hasRole("ADMIN")
    .anyRequest().authenticated()
)

访问 /admin-page 时,只有使用 admin 用户登录才可以通过。


五、常见问题解答(FAQ)

Q1:为什么我配置了 permitAll 却仍然需要登录?

可能原因:

  • 路径写错了(比如多了一个斜杠 /hello/
  • 顺序有误(后面的规则覆盖了前面的)

解决方法: 确认 .requestMatchers("/hello") 写法正确,并且放在 .anyRequest() 前面。

.authorizeHttpRequests(auth -> auth
    .requestMatchers("/hello").permitAll()
    .anyRequest().authenticated()
)

Q2:我的密码加密报错怎么办?

使用 withDefaultPasswordEncoder() 仅仅用于学习。如果换成正式加密方式(如 BCrypt),请记住:

  • 不要手动输入明文密码登录,要用加密后的
  • 推荐使用 PasswordEncoderFactories.createDelegatingPasswordEncoder() 来统一支持多种加密方式

Q3:我想改登录页的样式或路径怎么办?

你可以自定义登录页面,也可以使用 .loginPage("/my-login.html") 来指定自定义登录页。

Q4:有没有前后端分离的示例?

当然有!本教程讲解的是默认的 formLogin 模式,适合传统的 HTML 页面。如果你使用 Vue/React/Angular 等前后端分离技术,后续需要使用 Spring Security 的 JWT 模式OAuth2 认证

这部分内容我们将在下一篇文章中深入讲解。


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

数据库设计模型-1

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

以下是给初学者的学习路线图:

✅ 初级目标:掌握基础认证

  • 学习用户角色权限划分
  • 学会如何自定义登录页与登出行为
  • 熟悉常见的安全策略写法(URL 权限控制等)

📈 中级目标:结合数据库认证 + Token 支持

  • 使用 MySQL 数据库存储用户信息
  • 掌握 BCrypt 加密
  • 实现 JWT Token 验证(用于前后端分离系统)

🔧 高级目标:集成 OAuth2 & 多种认证方式

  • 使用 OAuth2 协议进行社交登录(微信、QQ、GitHub)
  • 实现 LDAP、SSO 单点登录
  • 安全审计与日志监控(如 IP 限制、失败登录次数限制)

结语

本文是一个 Spring Security 新手入门指南,从零开始搭建了一个包含用户认证和权限控制的基础项目。虽然只涉及了冰山一角,但已经为你打开了通往安全世界的大门。

如果你觉得这篇教程对你有帮助,不妨点赞收藏,并分享给你正在学习编程的朋友!

下一章我们将会进阶讲解「Spring Security + JWT」的组合用法,敬请期待!


📌 源码地址(建议收藏):
(此处可填写 GitHub 示例仓库链接)

📌 配套视频教程:
(如有配套教学视频,可附上 B站/Youtube 链接)


希望你能在学习的路上越走越远,写出更安全、可靠的企业级应用!🚀

评论 0

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