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

小镇程序员
2025-06-14 10:37
阅读 357

开篇:为什么需要 Spring Security?

开篇:为什么需要 Spring Security?

你有没有注意过,在使用某些网页时,必须先登录才能访问特定内容?比如网上银行、购物网站的订单页面、或者后台管理系统。这些功能背后的实现,就离不开“安全控制”机制。在 Java 后端开发中,Spring Security 就是这样一款用于保护 Web 应用程序的安全框架。

简单来说:

Spring Security 是一个用来保护你的 Web 项目的工具包,它可以帮你实现登录验证、权限管理、防御攻击等常见的安全需求。

对于初学者来说,不用一上来就想着理解所有的复杂概念,我们只需要从最基础的部分开始学习:如何让一个简单的网站拥有登录和权限控制的功能。本文将一步一步带你完成这个目标,即使是编程零基础也能轻松上手。


环境准备:搭建开发环境

环境准备:搭建开发环境

在开始实战之前,我们需要准备好开发环境。别担心,整个过程都很简单,而且很多工具都可以自动完成大部分工作。

所需工具列表:

  • Java JDK 8 及以上
  • IDE(推荐 IntelliJ IDEA 或 Eclipse)
  • Maven(项目构建工具)
  • Spring Boot Initializr(生成初始项目)

第一步:安装 Java

请到 官网下载 安装最新版 JDK。建议选择 LTS(长期支持)版本,如 JDK 8、JDK 11 或 JDK 17。

安装后可以在命令行输入以下命令检查是否安装成功:

java -version

输出类似如下内容,说明安装成功:

openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment (build 17.0.3+7-Ubuntu-122.04)
OpenJDK 64-Bit Server VM (build 17.0.3+7-Ubuntu-122.04, mixed mode, sharing)

第二步:安装 IDE

我们推荐使用 IntelliJ IDEA 社区版,它是免费的,并且对 Spring Boot 支持非常好。

下载地址:https://www.jetbrains.com/idea/download/

安装完成后打开它,稍后我们会用它来编写代码。


第三步:创建 Spring Boot 项目

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

按照下面的设置填写表单:

配置项 选项
Project Maven
Language Java
Spring Boot Version 最新稳定版(例如 2.7.x)
Project Metadata
Group com.example
Artifact securitydemo
Name SecurityDemoApplication
Packaging Jar
Java Version 17

然后点击 “Dependencies” 输入框,添加两个依赖:

  • Spring Web(Web 开发)
  • Spring Security(安全功能)

最后点击 Generate 下载项目压缩包。

解压后导入 IntelliJ IDEA:

  1. 打开 IDEA
  2. 点击 Open or Import
  3. 选择你解压后的项目文件夹
  4. 选择 Maven 并点击 OK

等待 Maven 自动下载依赖,这可能需要几分钟时间。


检查项目结构

导入后你会看到一个典型的 Spring Boot 项目结构:

securitydemo/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com.example.securitydemo/
│   │   │       ├── SecurityDemoApplication.java  // 主启动类
│   │   ├── resources/
│   │   │   └── application.properties

接下来,我们就要开始写第一个安全相关的代码了!


核心概念讲解:认识几个关键名词

在进入编码前,先了解一下几个核心概念。我们不讲复杂的术语,只说你能听懂的话。

1. 认证(Authentication)

想象你在进公司大楼时被保安拦下:“你是谁?”——这就是“认证”。你需要提供身份证或工牌信息,证明自己的身份。

对应到系统中就是:用户通过用户名和密码进行登录,系统验证是否正确。

2. 授权(Authorization)

保安确认你是员工后,又问:“你可以进几层?”——这就是“授权”。

对应到系统中就是:不同的用户有不同的权限等级,有些可以看数据,有些可以修改数据。

3. 用户信息存储(UserDetailsService)

Spring Security 提供了一个接口 UserDetailsService,它的作用是告诉系统有哪些用户、他们的账号密码和角色。

我们可以自定义这个接口,比如写一个内存中的用户数据库。

4. 过滤器链(Security Filter Chain)

这个听起来有点技术范儿,但其实它就像是一道道安检门。每个请求都要经过若干个安全检查步骤才能访问资源。

比如:

  • 是否已登录?
  • 有没有权限?
  • 是不是来自恶意 IP?

我们会在配置中定义这些规则。


✨小总结:你需要记住的概念

概念名称 通俗解释
Authentication(认证) 用户是谁?
Authorization(授权) 用户能做什么?
UserDetailsService 存储并提供用户信息的服务
Security Filter Chain 安全检查流程

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

现在我们真正动手做点东西!我们将完成以下几个任务:

  1. 创建一个简单的 Web 页面
  2. 配置基本的安全验证规则
  3. 设置内存中的用户账户
  4. 测试登录和权限控制

第一步:创建一个测试页面

我们在 src/main/java/com/example/securitydemo/ 文件夹中新建一个控制器类。

// HelloController.java
package com.example.securitydemo;

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

@RestController
public class HelloController {

    @GetMapping("/")
    public String home() {
        return "你好,欢迎来到主页!";
    }

    @GetMapping("/admin")
    public String adminPage() {
        return "这是管理员才能看到的内容。";
    }
}

保存后运行主类 SecurityDemoApplication,打开浏览器访问:

  • http://localhost:8080/ → 显示主页内容
  • http://localhost:8080/admin → 直接显示管理员内容

你会发现任何人都可以直接访问 /admin 页面。显然,这不是我们想要的效果。

那我们就来加上安全控制吧!


第二步:添加 Spring Security 配置类

新建一个类叫 SecurityConfig

// SecurityConfig.java
package com.example.securitydemo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {

    // 配置内存中的用户信息
    @Bean
    public InMemoryUserDetailsManager userDetailsManager() {
        UserDetails user = User.builder()
                .username("user")
                .password("{noop}123456")  // {noop} 表示不加密
                .roles("USER")
                .build();

        UserDetails admin = User.builder()
                .username("admin")
                .password("{noop}admin123")
                .roles("ADMIN")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    // 配置安全策略
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .requestMatchers("/").permitAll()
                .requestMatchers("/admin").hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .and()
            .httpBasic();
    }
}

这段代码做了两件事:

  1. 配置了两个用户:
    • user / 123456 → 普通用户
    • admin / admin123 → 管理员用户
  2. 定义了访问规则:
    • 主页任何人都可以访问
    • /admin 页面只有管理员能访问
    • 其他路径必须登录之后才能访问

第三步:测试访问

重启项目,再次访问:

1. 访问主页:

http://localhost:8080/
→ 不需要登录,正常显示“你好,欢迎来到主页!”

2. 访问管理员页面:

http://localhost:8080/admin
→ 会跳转到登录页面(Spring 自动提供的)

尝试用普通用户 user/123456 登录: → 页面提示你无权访问 /admin 路径。

再尝试用管理员账户 admin/admin123 登录: → 成功显示 “这是管理员才能看到的内容。”

✅ 大功告成!你现在拥有了一个具有基本安全认证功能的小系统。


✅常见新手问题 Q&A:

Q1:为什么密码前要加 {noop}

A:从 Spring Security 5 开始,默认要求密码必须是加密格式。为了方便教学演示,我们在前面加 {noop} 表示“不加密”,这样就能直接使用明文密码登录。

但在实际项目中,千万不要这样做!应该使用加密方式存储密码,比如 BCrypt。

Q2:为什么有的路径能匿名访问?

A:在 configure() 方法中设置了 .requestMatchers("/") 的路径为 permitAll(),也就是放行,不需要登录。

Q3:怎么自定义登录页面?

A:目前默认是 Spring 自带的登录页面。如果你希望自定义 HTML 页面,可以通过增加一个 login.html 页面,并在配置中设置 .formLogin().loginPage("/login") 来指定页面。

Q4:我忘记密码怎么办?

A:由于我们现在使用的是内存中的用户信息,重置密码的方式只能是改代码重新编译。后续你将学会从数据库加载用户信息,这时候就可以开发“找回密码”功能了。


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

恭喜你已经完成了第一个 Spring Security 项目的搭建!不过这只是开始,还有更多值得学习的内容:

建议 1:学习使用数据库保存用户

当前我们把用户信息写在代码里,属于“内存模式”。实际开发中用户数据通常是从数据库中读取的。

你可以在掌握 JDBC 或 JPA 后,尝试连接 MySQL 数据库,动态加载用户信息。

建议 2:了解加密处理

我们用了 {noop} 来忽略加密,这是不安全的做法。建议学习使用 BCryptPasswordEncoder 加密密码,更安全。

参考代码片段:

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

并在设置用户时去掉 {noop}

建议 3:深入研究方法级权限控制

我们只是配置了 URL 级别的权限控制,还可以通过注解方式控制具体方法的访问权限。

例如:

@PreAuthorize("hasRole('ADMIN')")
public String adminOnlyFunction() {
    return "Admin only!";
}

记得开启方法级注解:

@EnableMethodSecurity(prePostEnabled = true)

建议 4:学习 JWT 和 OAuth2(高级话题)

如果你打算开发前后端分离的项目(比如配合 Vue.js 或 React),可以学习 JSON Web Token(JWT)和 OAuth2 技术,它们是现代 Web 开发中的重要安全手段。


总结

本篇文章从“什么是安全控制”讲起,一步步教你搭建 Spring Boot + Spring Security 的最小认证系统。我们涵盖了:

  • 环境搭建
  • 核心概念讲解
  • 动手实现登录与权限控制
  • 常见问题解答
  • 学习路线建议

即使你是完全的新手,只要跟着步骤一步步操作,也可以轻松入门 Spring Security 的世界。记住,最好的学习方式就是实践!多动手、多调试,你一定会越来越熟练。

继续加油,成为安全领域的 Java 高手吧!

评论 0

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