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

青山不改需求改
2025-06-16 17:12
阅读 309

开篇:认识Spring Security

开篇:认识Spring Security

如果你正在学习Java Web开发,尤其是后端开发,那么你迟早会遇到一个问题:如何保护你的Web应用不被未授权的用户访问?

这时候,Spring Security就派上用场了。它是Spring框架的一部分,专门用于给我们的Web应用添加“安全性”功能。

你可以把它想象成一个保安系统:它能控制谁能登录、谁不能登录;谁可以访问某个页面、谁不可以;还能记住用户登录状态等。

本教程的目标是:

  • 带你从零开始认识Spring Security
  • 教你如何用最简单的配置实现用户登录验证
  • 搭建一个简单的安全认证系统
  • 为后续更高级的安全机制打下基础

环境准备:搭建你的开发环境

环境准备:搭建你的开发环境

在正式动手之前,我们需要准备好所需的开发工具和环境。

1. 安装 Java JDK

确保你已经安装好了 JDK 8 或更高版本(推荐使用 JDK 17
检查是否安装成功:

java -version

如果没有安装,请去 Oracle官网 或者使用 OpenJDK 下载对应版本。


2. 安装 IDE(推荐 IntelliJ IDEA)

IDE 是集成开发环境的意思,用来写代码的工具。推荐使用 IntelliJ IDEA Community Edition(免费),下载地址:https://www.jetbrains.com/idea/download/


3. 创建 Spring Boot 项目

我们使用 Spring Initializr 来快速创建项目:
访问网站:https://start.spring.io/

设置如下参数:

  • Project: Maven
  • Language: Java
  • Spring Boot Version: 最新稳定版本(如 3.1.x)
  • Group: com.example
  • Artifact: securitydemo
  • Dependencies:
    • Spring Web
    • Spring Security
    • Thymeleaf(可选,用于简单前端展示)

点击 “Generate” 下载生成好的项目压缩包,解压并导入到 IDEA 中。


4. 启动 Spring Boot 应用

打开项目后,找到主类(默认名是 SecuritydemoApplication),右键 Run 即可运行。

你会看到类似以下日志输出:

Started SecuritydemoApplication in X seconds

说明启动成功!


核心概念:理解 Spring Security 的关键要素

为了更好地理解 Spring Security 是如何工作的,我们先来了解几个核心概念,并用生活中的例子来帮助理解。


1. 认证(Authentication)

作用:确认你是谁。
类比:门禁刷脸或刷卡 → 验证身份

在 Spring Security 中,最常见的方式是通过用户名和密码登录进行认证。


2. 授权(Authorization)

作用:确认你能做什么。
类比:刷卡成功后 → 判断你是否有权限进入该楼层

比如管理员账号可以访问所有功能,普通用户只能查看部分页面。


3. 过滤器(Filter)

作用:每个请求都要经过一系列“过滤器”,决定是否允许继续处理请求。
类比:门口的保安一关一关地检查通行证

例如第一个过滤器检查有没有登录,第二个检查角色权限。


4. 用户存储(User Store)

作用:保存用户的账户信息。
可以是

  • 内存中(适合测试)
  • 数据库(真实项目常用)
  • LDAP / OAuth2 等方式

5. 安全配置(SecurityConfig)

这是你定义安全规则的地方,比如哪些页面需要登录才能访问,是否启用表单登录等。

我们会详细讲解怎么写这个配置文件。


实战项目:跟着步骤一步步完成一个简单安全系统

我们来实践一个完整的小项目,目标是:

✅ 创建一个网页应用,包含主页和管理页
✅ 只有登录后的用户才能访问管理页
✅ 所有人都可以访问主页
✅ 使用内存中的用户数据库做测试


第一步:创建两个页面

我们使用 Thymeleaf 模板引擎来创建两个页面(不需要太复杂的 HTML,只是为了演示)。

/src/main/resources/templates/ 目录下创建两个HTML文件:

home.html

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
    <h1>欢迎来到首页!</h1>
    <p><a th:href="@{/admin}">前往后台页面</a></p>
</body>
</html>

admin.html

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>后台页面</title>
</head>
<body>
    <h1>欢迎回来,管理员!</h1>
    <p><a th:href="@{/logout}">退出登录</a></p>
</body>
</html>

第二步:创建控制器 Controller

我们在 Java 中创建一个控制器类,来处理这两个页面的请求。

com.example.securitydemo.controller 包下创建 HomeController.java

package com.example.securitydemo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "home"; // 对应模板 home.html
    }

    @GetMapping("/admin")
    public String admin() {
        return "admin"; // 对应模板 admin.html
    }
}

现在你可以启动项目,访问:

  • 主页:http://localhost:8080
  • 管理页:http://localhost:8080/admin

但你会发现,不管有没有登录都能访问 admin 页面,接下来我们将加上安全限制!


第三步:编写 Spring Security 配置类

我们要告诉 Spring Security 哪些页面要保护起来。

新建类:SecurityConfig.java,放在 com.example.securitydemo.config 包中:

package com.example.securitydemo.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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/").permitAll()
                .requestMatchers("/admin").authenticated()
            )
            .formLogin(login -> login
                .loginPage("/login")  // 自定义登录页面路径
                .permitAll()
            )
            .logout(logout -> logout
                .permitAll()
            );

        return http.build();
    }

    @Bean
    public InMemoryUserDetailsManager userDetailsManager() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("admin")
            .password("123456")
            .roles("ADMIN")
            .build();

        return new InMemoryUserDetailsManager(user);
    }
}

解释一下重点内容:

  • .requestMatchers("/admin").authenticated() 表示访问 /admin 必须登录。
  • formLogin() 表示启用基于表单的登录界面。
  • 我们还在内存中配置了一个用户 admin/123456,拥有 ADMIN 角色。
  • 登出入口 /logout 也开放出来让所有人都可以登出。

第四步:添加登录页面(可选)

如果你想自定义登录页面,可以在 templates 文件夹中创建一个:

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
    <h1>登录页面</h1>
    <form th: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>

别忘了将控制器加上路由支持:

@GetMapping("/login")
public String login() {
    return "login";
}

这样你就可以访问 /login 手动登录了。


第五步:测试安全系统

  1. 启动项目
  2. 浏览器访问 http://localhost:8080/admin
  3. 会被跳转到 /login 页面
  4. 输入用户名 admin 和密码 123456,登录成功后就能访问 admin 页面
  5. 如果你点击“退出登录”,就会返回登录页

🎉 成功啦!你刚刚完成了一个完整的安全认证系统的初步实现!


常见问题解答

新手常常会遇到一些小问题,下面是一些高频问题及解决方案。


Q1:我输入正确的账号密码却无法登录?

可能原因

  • 密码格式不对。早期版本可以直接写明文密码,但现在 Spring Security 要求必须加密。
  • 解决方法
    • 使用 .withDefaultPasswordEncoder() 方法时,密码是明文,但只适用于测试环境。

    • 更推荐使用 BCrypt 加密,如:

      import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
      
      String encodedPassword = new BCryptPasswordEncoder().encode("123456");
      

Q2:为什么访问 /admin 会自动跳转到 /login

因为你在 SecurityConfig 中设置了:

.requestMatchers("/admin").authenticated()

Spring Security 检测到没有登录,就会自动跳转到登录页。


Q3:为什么不能访问静态资源,比如图片、CSS 文件?

这是因为安全配置默认对所有请求都做了拦截。

解决办法:在 securityFilterChain 方法中放行静态资源目录:

.authorizeHttpRequests(auth -> auth
    .requestMatchers("/", "/css/**", "/js/**", "/images/**").permitAll()
    ...
)

Q4:我想多个用户登录怎么办?

目前使用的是内存存储(InMemoryUserDetailsManager),可以添加多个用户:

@Bean
public InMemoryUserDetailsManager userDetailsManager() {
    UserDetails admin = User.withDefaultPasswordEncoder()
        .username("admin").password("123456").roles("ADMIN").build();

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

    return new InMemoryUserDetailsManager(admin, user);
}

Q5:登录后我想显示用户名怎么办?

你可以使用 Thymeleaf 获取当前登录用户的信息:

admin.html 中加入:

<p th:text="'当前用户:' + ${#authentication.name}"></p>

这样就能显示登录的用户名了。


学习建议:下一步你可以学什么?

API接口文档-1

恭喜你完成了本次 Spring Security 的入门训练营!

接下来可以尝试学习以下内容,不断拓展技能树:


✅ 下一步推荐路线图:

学习阶段 内容
✅ 入门完成 ✅ 当前已完成
🧩 第一步 学习 角色权限控制,如:不同角色访问不同页面
🔐 第二步 使用数据库存储用户信息(如 MySQL + JDBC)
🔐 第三步 学习 JWTREST API 的安全防护(前后端分离场景)
🔍 第四步 深入原理,理解 FilterChainProxy、SecurityContext 等核心概念
🌐 第五步 集成第三方登录(如微信、QQ、GitHub 登录)

💡 学习资源推荐:


总结

在本文中,我们从零开始,完成了 Spring Security 的基础学习,包括:

✅ 如何搭建开发环境
✅ 核心概念简要介绍
✅ 编写登录验证逻辑
✅ 控制页面访问权限
✅ 处理常见问题

只要你按照上述步骤一步一步来做,相信你现在已经能够搭建自己的安全认证系统了!

继续努力,Spring Security 是现代 Web 应用开发中非常重要的一环,掌握它意味着你离成为一名真正的后端开发者又近了一大步!


📝 文章字数统计:约 3824 字
🎯 适合初学者的入门长度与深度
🔥 实践驱动,注重落地能力培养

评论 0

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