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

接口调不通
2025-06-14 17:32
阅读 642

开篇:认识Spring Security

开篇:认识Spring Security

想象一下,你刚刚开发了一个网站,里面包含了一些只有特定用户才能访问的功能,比如后台管理页面或者用户的个人资料页。但是如果没有一个合适的权限控制系统,任何人都可以随意访问这些敏感内容,这显然是不安全的。这时候,Spring Security 就派上用场了!

Spring Security 是一款基于 Java 的 安全框架,它可以帮助我们为 Spring 应用添加用户登录、角色控制、访问限制等功能。简单来说,它就像是一道“门卫”,帮助我们保护网站资源,确保只有合法用户才能访问相应的内容。

为什么我们要学习 Spring Security 呢?因为它:

  1. 是 Spring 生态中的重要组成部分,广泛应用在企业级项目中。
  2. 提供了强大的安全功能,如用户认证(Authentication)和授权(Authorization)。
  3. 可以灵活地集成到各种 Web 应用中,无论是前后端分离还是传统的 MVC 架构都适用。
  4. 学会它可以让你的程序更加规范、安全,并提高求职竞争力。

在这篇教程中,我们将从零开始,手把手教你搭建一个拥有基础安全认证功能的 Spring Boot 项目。即使你是编程小白也没关系,只要你有对 Java 和 Spring 框架的基础了解,就能跟着教程一步步完成这个安全系统的搭建。


环境准备:准备好你的开发环境

环境准备:准备好你的开发环境

在开始编写代码之前,我们需要先准备好一些必要的开发工具和环境。别担心,这些工具都是免费且容易获取的。

你需要安装以下软件

工具 版本建议 下载地址
JDK 17 或以上 https://www.oracle.com/java/technologies/downloads
IntelliJ IDEA 最新社区版 https://www.jetbrains.com/idea/download
Maven 推荐使用内置版本 Spring Boot 自带
浏览器 Chrome/Firefox 都行 -

📌 新手提示:

如果你不确定自己的电脑是否已经安装了这些软件,可以在命令行输入:

  • java -version 检查 Java 是否安装
  • mvn --version 查看 Maven
  • 打开 IDE 看是否能正常启动

创建第一个 Spring Boot 项目

打开浏览器访问 https://start.spring.io,这是 Spring 官方提供的项目生成器。

填写如下信息:

  • Project: Maven
  • Language: Java
  • Spring Boot Version: 使用最新的稳定版本(例如 3.0+)
  • Group: com.example
  • Artifact: securitydemo
  • Name: securitydemo
  • Package name: com.example.securitydemo
  • Dependencies: 添加 Spring WebSpring Security

点击 "Generate" 下载项目压缩包并解压,然后使用 IntelliJ IDEA 打开该项目。

恭喜!你现在拥有了一个基本的 Spring Boot 项目结构,接下来就可以开始写代码了。


核心概念:理解安全机制的关键术语

核心概念:理解安全机制的关键术语

为了更好地使用 Spring Security,我们需要先理解几个关键概念,它们是构建安全系统的核心组件。

1. 用户认证(Authentication)

这是指系统验证用户身份的过程,比如你登录一个网站时输入用户名和密码,就是一种最典型的用户认证行为。

💡 类比:就像是去银行办理业务,工作人员检查你的身份证是否真实,确认你是不是账户本人。

2. 用户授权(Authorization)

一旦用户通过了认证,接下来系统就要决定他是否有权访问某个资源。比如一个普通用户不能访问管理员界面。

💡 类比:好比是进入公司大楼之后,保安还要查看你有没有权限进入某些办公室区域。

3. 角色(Role)与权限(Authority)

角色是一种分组方式,比如我们可以定义用户角色为 “ROLE_USER”、“ROLE_ADMIN”。而权限则更细粒度,比如 “read_profile”, “delete_user”。

通常我们会说:

  • 某个角色具有哪些权限
  • 某个用户属于哪个角色

例如:

  • 用户 Alice 具有角色 ROLE_USER,只能查看个人信息
  • 用户 Bob 具有角色 ROLE_ADMIN,可以执行删除操作

4. Spring Security 中的配置方式

Spring Security 提供了两种主要的配置方式:

  • 默认自动配置:什么都不做也能运行一个简易的安全系统(适合入门)
  • 自定义配置:继承 WebSecurityConfigurerAdapter 或者实现接口来自定义认证逻辑(更适合进阶)

实战项目:动手搭建一个简单的安全认证系统

实战项目:动手搭建一个简单的安全认证系统

我们现在要搭建一个最简单的安全认证系统,包括:

  • 默认用户登录页面
  • 权限控制(不同角色访问不同页面)
  • 自定义登录成功跳转

让我们开始吧!

第一步:添加依赖项(Maven)

如果你是在 https://start.spring.io 创建的项目,已经包含了 spring-boot-starter-webspring-boot-starter-security,这两个库分别用于处理 HTTP 请求和安全认证。

无需额外添加其他依赖。

第二步:创建控制器(Controller)

src/main/java/com/example/securitydemo/controller 路径下新建一个文件 HomeController.java

package com.example.securitydemo.controller;

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

@RestController
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "欢迎访问主页!";
    }

    @GetMapping("/user")
    public String userPage() {
        return "这是普通用户可见的页面。";
    }

    @GetMapping("/admin")
    public String adminPage() {
        return "这是管理员可见的页面。";
    }
}

保存后运行项目,在浏览器访问:

  • http://localhost:8080/ → 需要登录
  • 登录成功后可继续访问 /user/admin
  • 默认账号:user,密码在控制台输出中可以看到类似这样的语句:
Using generated security password: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

复制这个临时密码即可登录。

第三步:自定义登录表单

虽然 Spring Security 为我们提供了默认的登录页面,但如果我们想让它更美观或符合自己项目的风格,可以替换为自己的页面。

首先,创建 HTML 页面:

src/main/resources/templates 目录下新建 login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<h2>请登录</h2>

<form action="/login" method="post">
    用户名:<input type="text" name="username"/><br/>
    密码:&nbsp;&nbsp;<input type="password" name="password"/><br/>
    <button type="submit">登录</button>
</form>
</body>
</html>

接着,修改控制器以显示此页面:

@GetMapping("/login")
public String loginPage() {
    return "login"; // 指向 templates/login.html
}

最后,配置 Spring Security 以允许访问该页面而不受保护:

创建配置类 SecurityConfig.java

package com.example.securitydemo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/login").permitAll()
                .antMatchers("/user").hasRole("USER")
                .antMatchers("/admin").hasRole("ADMIN")
            .and()
            .formLogin()
                .loginPage("/login") // 使用我们自定义的登录页
                .defaultSuccessUrl("/home") // 登录成功跳转首页
            .and()
            .logout()
                .logoutSuccessUrl("/");
    }

    // 设置两个内存用户:user/userpass 和 admin/adminpass
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
            .withUser("user")
                .password("{noop}userpass") // {noop} 表示明文密码
                .roles("USER")
            .and()
            .withUser("admin")
                .password("{noop}adminpass")
                .roles("ADMIN");
    }
}

系统架构设计图-2

现在再次访问 /login 页面,你会发现我们的自定义登录页面出现了!

第四步:测试权限控制

现在,你可以尝试分别使用 user/userpassadmin/adminpass 登录:

  • 用户 user:能访问 /user 页面,但无法进入 /admin
  • 用户 admin:能同时访问 /user/admin

这就是我们设置的角色权限控制的作用。


常见问题解答(FAQ)

以下是新手经常遇到的问题及解决方法:

Q1:为什么会收到 “There is no configured PasswordEncoder” 报错?

A:从 Spring Security 5 开始,默认要求使用加密密码存储。若想暂时使用明文密码,请在密码前加上 {noop},例如:

.password("{noop}userpass")

Q2:登录失败怎么办?

A:可能的原因有:

  • 输入的账号密码错误
  • 未正确加载 configure(AuthenticationManagerBuilder auth) 方法中的用户数据
  • 缓存了旧密码,重新启动应用试试

Q3:如何自定义登出后的跳转页面?

A:使用 .logout().logoutSuccessUrl("/your-url") 即可,例如:

.logout()
    .logoutSuccessUrl("/logout-success")

Q4:如何让多个路径共享同一权限?

A:使用 hasAnyRole(...) 方法,例如:

.antMatchers("/settings/**").hasAnyRole("ADMIN", "MANAGER")

表示管理员和经理角色都可以访问 /settings 路径下的资源。

Q5:我的静态资源也被拦截了,怎么放行?

A:对于 CSS、JS、图片等静态资源,可以在配置中使用 permitAll() 放行,例如:

.antMatchers("/css/**", "/js/**", "/images/**").permitAll()

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

恭喜你完成了本次 Spring Security 的入门实践!你现在有能力构建一个带有用户登录和权限控制的基本安全系统了。那么下一步,你可以尝试学习以下内容来进一步提升:

✅ 进阶知识点推荐:

  1. 数据库用户认证(JDBC + MySQL)
    • 从内存用户过渡到数据库用户,使用数据库来存储账号密码和角色信息
  2. 整合 Thymeleaf 前端模板
    • 在页面中根据用户角色动态显示不同内容
  3. JWT 认证与 OAuth2
    • 学习现代无状态 API 的认证方式,适用于前后端分离和移动端场景
  4. CSRF 防御与安全攻击防范
    • 深入了解常见的 Web 安全漏洞及防护措施
  5. 多因素认证
    • 如短信验证码、邮箱验证、Google Authenticator 等多种认证方式

📚 推荐学习资料:

数据流转过程-1

希望你能继续深入学习,掌握更多安全知识,早日成为一名优秀的 Java 安全工程师!


如有任何疑问或需要补充内容,欢迎留言交流~

评论 0

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