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

接口余额不足
2025-06-19 07:43
阅读 760

开篇:Spring Security 是什么?它能用来做什么?

开篇:Spring Security 是什么?它能用来做什么?

如果你刚开始接触后端开发,可能会对“安全”这个概念感到有些抽象。简单来说,安全性(Security)就是保护你的网站或应用不被未授权的用户访问和破坏。比如,你希望只有登录了的用户才能查看某个页面,或者某些敏感操作只能由管理员执行,这时候你就需要用到像 Spring Security 这样的工具。

那 Spring Security 到底是什么?

Spring Security 是一个专门为 Java 应用设计的安全框架,主要用于给我们的 Web 项目添加各种安全功能,如:

  • 登录认证(Authentication)
  • 权限控制(Authorization)
  • 防止攻击(如 CSRF、Session Fixation 等)
  • 用户权限管理(如管理员、普通用户等角色)

你可以把它想象成是给你的网站装了一扇门,这扇门可以根据不同的人设置不同的进入权限——Spring Security 帮我们自动完成了这个“装门”的过程,并提供了丰富的开关策略。


环境准备:搭建你的第一个 Spring Boot + Spring Security 环境

环境准备:搭建你的第一个 Spring Boot + Spring Security 环境

在开始写代码之前,我们需要先准备好开发环境。

第一步:安装 Java 开发环境

确保你已经安装了以下软件:

  • JDK 17 或以上版本
  • Maven(用于依赖管理)
  • IDE(推荐 IntelliJ IDEA 或 Eclipse)

🧪 检查是否安装成功:

打开命令行输入以下命令:

java -version
mvn -v

如果有输出 Java 和 Maven 的版本信息,说明安装成功!


第二步:创建一个新的 Spring Boot 项目

你可以使用 Spring Initializr 来生成一个 Spring Boot 项目骨架。

配置如下:

  • Project: Maven
  • Language: Java
  • Spring Boot Version: 3.x (选择最新稳定版)
  • Group: com.example
  • Artifact: spring-security-demo
  • Dependencies:
    • Spring Web
    • Spring Security

点击 Generate 按钮下载项目压缩包并解压到本地目录中。


第三步:导入项目并运行

  1. 使用 IntelliJ IDEA 打开该项目。
  2. 等待 Maven 下载所有依赖。
  3. 找到主类 SpringSecurityDemoApplication.java 并右键 Run,启动应用。

此时你应该看到类似这样的输出:

Tomcat started on port(s): 8080 (http)
Started SpringSecurityDemoApplication in X seconds

表示项目启动成功!


核心概念:什么是认证、授权?它们有什么区别?

接下来我们要了解两个最重要的术语:认证(Authentication)授权(Authorization)

概念 含义说明
认证(Authentication) 确定你是谁,验证身份的真实性。比如输入用户名和密码登录系统。
授权(Authorization) 决定你能不能做某件事。比如用户 A 能访问主页但不能删除数据,而管理员可以。

💡 就像坐飞机时的身份核验一样:

  • 安检前:验证你的身份证 → 认证
  • 登机口:凭票登机 → 授权

这两个步骤通常是前后关系:先确认你是谁,再判断你能干什么。


Spring Security 中几个重要的类/组件

为了更直观地理解这些概念,我们来介绍几个 Spring Security 的核心组件:

组件名 作用说明
UserDetailsService 加载用户的信息(比如从数据库读取)
PasswordEncoder 对密码进行加密比较
SecurityFilterChain 定义请求的安全规则(比如哪些路径要拦截)
AuthenticationManager 处理用户的登录认证逻辑

我们会在实战项目中详细用到这些内容。


实战项目:一步步完成简单的登录认证系统

现在让我们来动手做一个最简单的登录认证系统吧!

第一步:创建两个控制器(Controller)

src/main/java/com/example/springsecuritydemo/controller 目录下创建两个文件:

HomeController.java

package com.example.springsecuritydemo.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 "这是管理员页面";
    }
}

目前所有页面都是公开可访问的,接下来我们将通过 Spring Security 添加权限控制。


第二步:配置基本的登录验证(基于内存账户)

我们在项目中添加一个安全配置类 SecurityConfig.java

SecurityConfig.java

package com.example.springsecuritydemo.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;


![微服务架构示意图-1](https://code-guide.oss.shanghai.autogptai.club/common/file/download?name=date2025061907/aa6d7f71-5b9e-42b9-92d6-9c4248454c11.jpg)


@Configuration
public class SecurityConfig {

    // 创建两个内存用户
    @Bean
    public InMemoryUserDetailsManager userDetailsManager() {
        UserDetails user = User.withDefaultPasswordEncoder()
                .username("user")
                .password("123456")
                .roles("USER")
                .build();
        
        UserDetails admin = User.withDefaultPasswordEncoder()
                .username("admin")
                .password("admin123")
                .roles("ADMIN")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    // 安全规则定义
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(config -> config
                        .requestMatchers("/").permitAll()
                        .requestMatchers("/user").hasRole("USER")
                        .requestMatchers("/admin").hasRole("ADMIN")
                )
                .formLogin(login -> login.loginPage("/login")) // 自定义登录页
                .logout(logout -> logout.logoutSuccessUrl("/")); // 注销后的跳转页


![系统架构设计图-2](https://code-guide.oss.shanghai.autogptai.club/common/file/download?name=date2025061907/c885b356-c2e1-4b5e-b1e8-ddc628ecaae4.jpg)


        return http.build();
    }
}

这段代码做了几件事:

  • 定义了一个内存中的用户管理系统;
  • 规定了 /user 页面只能 USER 角色访问;
  • 规定了 /admin 页面只能 ADMIN 角色访问;
  • 提供了一个自动生成的登录页面(默认地址为 /login);
  • 支持注销功能,默认跳转回首页。

第三步:测试访问效果

启动应用之后,尝试访问以下地址:

URL 预期结果
http://localhost:8080/ 可以直接访问
http://localhost:8080/user 自动跳转到登录页,需输入 username: user / password: 123456
http://localhost:8080/admin 需要用 admin 账号登录
http://localhost:8080/login 显示登录页面

💡 提示:默认会自动生成一个登录页面。如果你想要自定义样式,可以在后续学习中覆盖 /login 页面的 HTML。


常见问题解答(FAQ)

下面是新手常遇到的问题与解决方法。

Q1:为什么我设置了用户名和密码,还是无法登录?

常见原因:

  • 密码没有正确加密(本教程中用了 .withDefaultPasswordEncoder(),仅适合演示用途)
  • 忘记了关闭 CSRF(如果是手动提交表单)
  • 浏览器缓存了旧 Cookie,导致混乱

✅ 解决办法:

  • 确保密码格式与加密方式匹配(后续我们会讲到如何正确使用 BCrypt)
  • 清除浏览器缓存或换一个浏览器试试

Q2:如何退出登录?

默认情况下,Spring Security 提供的是 /logout 的 POST 请求,我们可以使用如下方式登出:

方式一:使用 curl 模拟注销

curl -X POST http://localhost:8080/logout

方式二:前端页面加一个退出按钮(HTML 示例)

<form action="/logout" method="POST">
    <input type="submit" value="退出登录" />
</form>

别忘了开启 CSRF 保护(默认已启用),否则 POST 请求会被拒绝。


Q3:我想让某个接口不需要登录就可以访问怎么办?

使用 .permitAll() 方法即可放行:

.requestMatchers("/public/**").permitAll()

比如 /public/data 这个路径就不需要登录也能访问。


Q4:我怎么知道当前用户是谁?

可以用 @AuthenticationPrincipal 注解获取当前用户对象:

@GetMapping("/whoami")
public String whoAmI(@AuthenticationPrincipal String username) {
    return "你当前登录的用户名是:" + username;
}

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

恭喜你完成了 Spring Security 的基础入门实践!为了进一步深入掌握这项技术,你可以继续学习以下几个方向:


✅ 更安全的密码存储方式

  • 学习使用 BCryptPasswordEncoder 替代 .withDefaultPasswordEncoder()
  • 在数据库中实现用户管理(JPA + Security)

✅ 权限控制进阶

  • 使用 hasAuthority() 替代 hasRole() 实现更细粒度的权限划分
  • 自定义权限注解,实现方法级别的权限控制(如 @PreAuthorize

✅ 集成第三方登录(OAuth2)

  • 使用 GitHub、微信等作为登录渠道
  • 学习 OAuth2 协议流程以及 Spring Security OAuth2 的集成方式

✅ 前后端分离场景下的安全机制

  • 学习 JWT(JSON Web Token)的使用方式
  • 整合 Vue / React 前端与 Spring Security 的 Token 认证

结语

通过这篇教程,你应该已经掌握了使用 Spring Security 实现基础认证的方法。记住一句话:

编程不是死记硬背,而是边做边悟。

每当你写完一段代码,试着问自己:“它到底做了什么?有没有更好的方式?”这样持续思考,你会成长得更快。

如果喜欢这种教学风格,请点赞或留言告诉我你最想看下一节讲解哪部分内容!


📌 文章总字数约 3386 字。

评论 0

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