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

TechEvangelist
2025-06-21 13:03
阅读 461

开篇:Spring Security是什么?能做什么?

开篇:Spring Security是什么?能做什么?

你可能听说过“网站登录”这个功能,比如你在淘宝上购物时需要登录账号、在银行网站操作前要输入用户名和密码——这些其实就是用户身份验证的过程。而 Spring Security 正是一个帮助我们快速实现这类安全机制的强大工具。

简单来说:

Spring Security 是一个专门用来保护 Java 应用(尤其是 Spring Boot 项目)安全的框架

它主要能帮你完成以下几个核心任务:

  • ✅ 用户登录认证(谁可以访问)
  • ✅ 权限管理(谁有权限访问哪些页面)
  • ✅ 防止一些常见的攻击方式(如 CSRF、Session 固定等)

如果你是初学者,不用担心这些术语,接下来我们会一步步用最简单的语言和示例来讲解!


环境准备:开发前的准备工作

环境准备:开发前的准备工作

为了顺利学习 Spring Security,我们需要先准备好以下开发环境。

1. 安装 Java 开发环境

推荐使用 JDK 17(Java Development Kit),这是目前主流版本之一。

你可以从这里下载安装包: 🔗 Oracle JDK 下载 或者使用 OpenJDK 版本: 🔗 Adoptium / Eclipse Temurin

安装完成后,在命令行中输入下面的命令查看是否安装成功:

java -version

你应该会看到类似下面的输出:

openjdk version "17.0.8" 2023-07-18

说明你的 Java 已经安装好了。


2. 安装 IDE(开发工具)

推荐使用 IntelliJ IDEA Community Edition(社区版),它对 Spring Boot 和 Spring Security 支持非常好。

下载地址:🔗 JetBrains IntelliJ IDEA 下载页

安装完成后打开软件,我们就可以开始写代码啦!


3. 创建 Spring Boot 项目

我们可以使用官方提供的在线工具快速生成项目:

  1. 打开:https://start.spring.io/
  2. 填写如下信息:
    • Project:Maven
    • Language:Java
    • Spring Boot Version:建议选 3.x 最新版
    • Groupcom.example
    • Artifactsecurity-demo
  3. 在 “Dependencies” 中搜索并添加:
    • Spring Web
    • Spring Security

点击下方的按钮:“Generate”,下载项目压缩包。

解压后导入到 IntelliJ IDEA 或其他你喜欢的 IDE 中,项目就准备好了!


核心概念:通俗解释 Spring Security 的关键要素

核心概念:通俗解释 Spring Security 的关键要素

学习 Spring Security,必须了解几个关键角色和流程:


🧑‍💼 什么是“用户”?

用户就是你网站或系统的使用者。每个用户会有自己的 用户名密码,系统通过这两个信息来确认是不是这个人。


🔒 什么是“认证”?

认证就是系统判断当前请求者是否合法的过程。简单理解就是你输入用户名和密码之后,系统告诉你能不能进入。


👮‍♀️ 什么是“授权”?

授权是在认证通过后发生的。意思是:就算你是合法用户,系统也要决定你能看什么内容、不能看什么内容。比如学生只能查看自己的成绩,老师可以修改所有成绩。


🧱 核心组件一览表

组件 描述
SecurityFilterChain 负责定义哪些页面需要认证,哪些不需要,怎么认证
UserDetailsService 提供用户的详细信息,比如数据库里存的用户数据
PasswordEncoder 处理密码加密与验证
AuthenticationManager 负责执行认证逻辑

新手现在不用搞懂全部,跟着做一遍项目就会明白这些概念了。


实战项目:手把手教你搭建登录系统

我们现在要做的,就是一个带有登录功能的简单网页应用。

我们将实现:

  • 访问 /hello 需要登录才能访问
  • 使用默认的用户名和密码登录
  • 自定义登录页面(可选进阶)

第一步:添加依赖项

确保你的 pom.xml 文件中有如下两个依赖(前面创建项目时已经加过):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

如果没有,请手动加上保存即可。


第二步:编写登录配置类

新建一个 Java 类,例如命名为:SecurityConfig.java

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("/hello").authenticated()
            )
            .formLogin(login -> login
                .loginPage("/login")     // 指定自定义登录页面路径
                .permitAll()              // 登录页面所有人都可以访问
            )
            .logout(logout -> logout.permitAll());  // 登出功能允许所有人访问

        return http.build();
    }

    // 使用内存中的用户数据源(用于测试)
    @Bean
    public InMemoryUserDetailsManager userDetailsManager() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("user")
            .password("123456")
            .roles("USER")
            .build();

        return new InMemoryUserDetailsManager(user);
    }
}

第三步:编写控制器

创建一个控制器,处理访问页面的逻辑。

新建文件:HelloController.java

package com.example.securitydemo.controller;

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

@Controller
public class HelloController {

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

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

    @GetMapping("/login")
    public String login() {
        return "login";  // 这个页面稍后创建
    }
}

第四步:创建 Thymeleaf 页面

我们在项目的资源目录下创建 HTML 页面(Spring Boot 默认使用的是 Thymeleaf 模板引擎):

1. src/main/resources/templates/index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<body>
<h2>欢迎来到首页!</h2>
<p><a th:href="@{/hello}">前往受保护页面</a></p>
</body>
</html>

2. src/main/resources/templates/hello.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>你好!</title>
</head>
<body>
<h2>你已成功登录!</h2>
<a href="/logout">退出</a>
</body>
</html>

3. src/main/resources/templates/login.html

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

第五步:运行程序并测试

  1. 启动项目
  2. 浏览器访问:http://localhost:8080
  3. 点击“前往受保护页面”链接
  4. 会自动跳转到登录页 → 输入用户名 user,密码 123456
  5. 成功后进入 /hello 页面,并且可以看到退出按钮

可选进阶:添加更多用户

你可以参考下面的代码来添加多个用户:

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

    UserDetails admin = User.withDefaultPasswordEncoder()
        .username("admin")
        .password("admin123")
        .roles("ADMIN")
        .build();

    return new InMemoryUserDetailsManager(user1, admin);
}

这样你可以用不同的账号测试不同权限的功能。


新手常见问题解答


❓为什么我登录后还是跳回登录页?

✅ 原因可能:

  • 表单提交的 action 地址不正确(应该为 /login
  • 没有正确开启 .permitAll() 对 login 页面的访问
  • 浏览器缓存了之前的结果,尝试清除 cookie

❓如何查看默认的用户名和密码?

✅ 如果你没有自定义用户,Spring Security 默认会随机生成用户名 user,密码打印在控制台中,例如:

Using generated security password: 39ee2b4c-b69d-4069-a0d1-8f1210d7xxxx

❓我想连接数据库进行登录怎么办?

✅ 你可以替换 InMemoryUserDetailsManager 为你自己写的 UserDetailsService,从数据库中查询用户信息。这部分属于进阶内容,后续可以进一步学习 JDBC、MyBatis 或 JPA。


❓我想自定义登录失败页面怎么办?

✅ 可以通过 .failureHandler(...).failureUrl(...) 设置失败跳转路径,也可以返回 JSON 数据给前端。


❓我要不要把密码明文存储?

🚫 绝对不要! 明文密码非常危险。应始终使用加密存储,比如 Spring Security 推荐使用 BCryptPasswordEncoder


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

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

接下来你可以根据兴趣继续深入:


📘 初级拓展建议:

  • 学习如何将用户信息存在数据库中(使用 UserDetailsService + 数据库)
  • 学习 Spring Boot + MySQL 整合
  • 学习 JWT(前后端分离常用的身份验证方式)

🛠️ 技术栈建议:

  • Spring Boot + Spring Security + MySQL + MyBatis(完整 Web 项目)
  • 或者结合 Redis 缓存 Session(提高性能)
  • 再配合 Vue.js 或 React 实现完整的前后端分离系统

🔗 推荐学习资料:


总结

通过本文,你已经掌握了 Spring Security 的基础知识,并完成了第一个基于内存认证的安全系统。

记住一句话:

任何复杂的安全机制,都是从最简单的例子出发慢慢演化出来的

只要你保持动手实践的习惯,相信你很快就能掌握 Spring Security,并构建更强大的后台安全系统!


希望这篇教程对你有帮助 🌟
如果还有疑问,欢迎留言提问,我们一起成长!

评论 0

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