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

邓文
2025-06-15 05:25
阅读 720

开篇:Spring Security 是什么?为什么我要学?

开篇:Spring Security 是什么?为什么我要学?

你有没有遇到过这样的场景:你开发了一个网站,里面有登录页、用户信息页面,还有一些只有登录后才能访问的内容。你想确保“没有授权的人”不能随便访问这些页面。这时候,你就需要一个权限控制工具来帮你管理这个过程。

Spring Security 就是这样一个工具——它是 Java Web 开发中用于实现权限控制的主流框架之一。它可以帮你轻松实现:

  • 用户登录功能
  • 权限控制(哪些人能访问哪些页面)
  • 数据加密(比如密码存储)
  • 防止常见攻击(如 CSRF)

本教程将带你从零开始,用最简单的方式入门 Spring Security。你不需要会任何安全知识,只要会写基本的 Spring Boot 应用即可!


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

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

数据流转过程-2

在开始之前,你需要准备好以下开发环境:

1. JDK 安装

Spring Boot 需要安装 Java 开发环境。推荐使用 JDK 17 或以上版本

你可以前往 Oracle JDK 下载页面OpenJDK 下载并安装。

提示:安装完成后,在终端输入 java -versionjavac -version 看是否输出了版本号。

2. IDE 推荐

推荐使用以下两款之一:

  • IntelliJ IDEA(社区版免费)
  • Eclipse 或 STS(Spring Tool Suite)

下载地址:

3. 创建 Spring Boot 项目

我们使用 Spring Initializr 来创建项目:

访问:https://start.spring.io/

填写如下内容:

  • Project: Maven
  • Language: Java
  • Spring Boot Version: 3.x(例如 3.0.5)
  • Group: com.example
  • Artifact: springsecuritydemo
  • Name: springsecuritydemo
  • Packaging: Jar
  • Java Version: 17

添加依赖项:

  • Spring Web(构建 Web 应用)
  • Spring Security(本课核心)
  • Thymeleaf(可选,用于展示页面)

点击 Generate,下载项目并解压到你喜欢的位置。

然后用 IDE 打开该项目。你会看到一个标准的 Spring Boot 结构。


核心概念:什么是用户、角色、权限?

核心概念:什么是用户、角色、权限?

在正式开始编码之前,我们先了解几个关键概念。这些词听起来有点专业,但我保证你能听懂:

1. 用户(User)

就像你在知乎、B站注册的账号一样,每个用户都有唯一的用户名和密码。Spring Security 可以管理这些用户。

2. 角色(Role)

角色是用来对用户进行分类的一种方式。比如:

  • 普通用户(ROLE_USER)
  • 管理员(ROLE_ADMIN)

角色可以帮助我们决定:谁可以做什么事情。

3. 权限(Authority)

权限比角色更细粒度。比如某个管理员角色有:

  • 查看用户列表的权限
  • 删除用户的权限

权限通常用来控制具体的操作行为。

4. 认证(Authentication)

就是验证你是不是那个用户的过程。比如你输入用户名和密码,系统判断你是谁。

5. 授权(Authorization)

认证之后,系统会根据你的身份(用户、角色、权限)判断你能不能做某件事。


实战项目:一步步实现登录与权限控制

我们来做一个简单的网页应用,里面有两个页面:

  1. 普通用户首页(所有人可见)
  2. 管理员后台(只能管理员访问)

并且我们将实现:

  • 内存中的两个用户:user(普通用户)、admin(管理员)
  • 登录页面由 Spring Security 自动生成

Step 1:配置安全规则

打开你的项目,找到 SpringsecuritydemoApplication.java 文件旁边,新建一个类叫 SecurityConfig.java,内容如下:

package com.example.springsecuritydemo;

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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

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

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

        UserDetails admin = User.withUsername("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("/").permitAll()
                .requestMatchers("/admin").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(login -> login.permitAll()) // 启用默认登录页
            .logout(logout -> logout.permitAll());


![系统架构设计图-1](https://code-guide.oss.shanghai.autogptai.club/common/file/download?name=date2025061505/be228154-da8b-4765-b23e-259a4bb7e64a.jpg)


        return http.build();
    }
}

这段代码做了几件重要的事:

  • 使用内存保存用户(方便新手学习)
  • 设置了两个用户:user 和 admin
  • / 页面开放所有人访问
  • /admin 页面设置仅允许 ROLE_ADMIN 角色访问
  • 启用了默认的登录和登出功能

Step 2:编写简单的控制器

创建一个新的类:HomeController.java

package com.example.springsecuritydemo;

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

@Controller
public class HomeController {

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

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

Step 3:创建 Thymeleaf 页面

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

home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>主页</title>
</head>
<body>
<h1>欢迎来到主页!</h1>
<p><a href="/admin">进入后台管理页面</a></p>
<p><a href="/login">登录</a> | <a href="/logout">登出</a></p>
</body>
</html>

admin.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>管理员页面</title>
</head>
<body>
<h1>欢迎管理员!</h1>
<p><a href="/">返回主页</a></p>
</body>
</html>

Step 4:运行项目

回到你的 IDE,运行 SpringsecuritydemoApplication.java 启动项目。

访问:

  • http://localhost:8080/ → 主页
  • http://localhost:8080/admin → 管理员页面(会跳转到登录页)

尝试使用下面两个账户登录:

  • user / 123456
  • admin / admin123

看看权限是否生效。


常见问题解答(FAQ)

Q: 登录的时候提示“Bad credentials”,怎么办?
A: 密码错误或者没有被正确加密。请确认你使用的是 BCryptPasswordEncoder,并且密码是在代码里经过 .encode() 处理过的。

Q: 我想把用户存在数据库里,怎么做?
A: 这个进阶功能我们会在下一节课讲。目前先掌握用内存用户的方式。

Q: 页面一直跳回登录页,怎么调试?
A: 检查路由规则是否匹配正确,也可以加日志或断点跟踪请求路径。

Q: 我不想让某些接口走权限校验怎么办?
A: 在 securityFilterChain 中使用 .requestMatchers("/path").permitAll() 即可。

Q: 为什么建议用 BCrypt 加密而不是明文?
A: 明文存储密码太危险了。BCrypt 是一种单向加密算法,即使数据泄露,也无法还原原始密码。


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

如果你已经完成了上面的实战练习,恭喜你迈出了 Spring Security 的第一步!

接下来你可以尝试:

  1. 【进阶】使用数据库代替内存用户(学习 JPA + 自定义 UserDetailsService)
  2. 【增强】集成第三方登录(如 GitHub、QQ 登录)
  3. 【实战】为 REST API 添加 Token 认证(JWT)
  4. 【攻防】防止常见漏洞(CSRF、XSS)

你可以参考官方文档:https://docs.spring.io/spring-security/reference/html/

当然,最重要的是多动手实践!边学边敲代码,边改边理解原理,进步最快。


小结一下我们今天学了什么?

✅ 初识 Spring Security
✅ 准备好了开发环境
✅ 了解了用户、角色、权限等核心概念
✅ 实现了一个带登录和权限控制的小项目
✅ 解决了新手常见问题
✅ 规划了进一步的学习方向

你已经掌握了 Spring Security 的核心思想和初步能力,继续加油吧!

评论 0

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