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

后端说没问题
2025-12-14 20:43
阅读 613

大家好,我是小林,一名211高校的计算机专业研究生,平时喜欢在GitHub上写技术博客帮助刚入门的学弟学妹们。最近很多同学私信问我:“Spring Security到底怎么用?能不能写个零基础教程?”我当初学的时候也踩过不少坑——光是看官方文档就头晕,配置一错整个项目就跑不起来。所以今天,我就带大家用一个完整的实战项目,从零开始搭建一个最基础但能跑通的安全认证系统。

为什么需要 Spring Security?

想象一下:你做了一个后台管理系统,任何人都能直接访问 /admin 页面删除数据——这太危险了!Spring Security 就是 Spring 家族中专门用来处理“谁可以访问什么”的安全框架。它能帮你轻松实现:

  • 用户登录认证(Authentication)
  • 权限控制(Authorization)
  • 防止常见攻击(如 CSRF、XSS)

而我们今天的目标,就是用 Java + Spring Boot 快速搭一个带登录页面的 Web 应用,并限制未登录用户访问特定页面。


环境准备:5分钟搞定开发环境

💡 建议使用 IntelliJ IDEA(社区版免费),搭配 JDK 17 或 JDK 8。

步骤 1:创建 Spring Boot 项目

访问 https://start.spring.io,填写以下信息:

配置项
Project Maven
Language Java
Spring Boot 3.2.x(最新稳定版)
Group com.example
Artifact security-demo

Dependencies 中添加:

  • Spring Web
  • Spring Security
  • Thymeleaf(用于简单页面渲染)

点击 Generate 下载 ZIP,解压后用 IDEA 打开。

步骤 2:验证项目能跑起来

打开 SecurityDemoApplication.java,点击运行。如果看到类似下面的日志,说明环境 OK:

Tomcat started on port(s): 8080

浏览器访问 http://localhost:8080 —— 别慌!即使你没写任何代码,Spring Security 也会自动拦截所有请求,跳转到默认登录页!

🔍 新手疑问:为什么我访问首页却跳到了 /login

这是因为 Spring Security 默认开启“全站保护”,任何请求都需要认证。别担心,我们马上自定义它!


核心概念:认证 vs 权限,到底有什么区别?

很多初学者会混淆这两个概念,我用一句话讲清楚:

  • 认证(Authentication):你是谁? → 比如用户名密码是否正确
  • 授权(Authorization):你能干什么? → 比如普通用户不能删数据,管理员可以

在 Spring Security 中,我们通过 配置类 来定义这些规则。


实战项目:手把手搭建一个带登录的后台

我们的目标:
✅ 访问 / 首页无需登录
✅ 访问 /admin 必须登录,且用户名为 admin

第一步:创建简单的 HTML 页面

src/main/resources/templates 下新建两个文件:

index.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>首页</title></head>
<body>
  <h1>欢迎来到首页!</h1>
  <a href="/admin">进入管理后台</a>
</body>
</html>

admin.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>管理后台</title></head>
<body>
  <h1>管理员专属页面</h1>
  <p>只有 admin 能看到这里!</p>
  <a href="/">返回首页</a>
</body>
</html>

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

// src/main/java/com/example/securitydemo/controller/HomeController.java
package com.example.securitydemo.controller;

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

@Controller
public class HomeController {

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

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

第三步:关键!配置 Spring Security

创建配置类:

// src/main/java/com/example/securitydemo/config/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.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;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/").permitAll()      // 首页无需登录
                .requestMatchers("/admin").hasRole("ADMIN") // /admin 需要 ADMIN 角色
                .anyRequest().authenticated()          // 其他所有请求需登录
            )
            .formLogin(form -> form
                .loginPage("/login")                   // 使用自定义登录页(可选)
                .permitAll()
            )
            .logout(logout -> logout.permitAll());

        return http.build();
    }

    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        // 创建内存中的用户(仅用于演示!生产环境请用数据库)
        UserDetails admin = User.builder()
            .username("admin")
            .password("{noop}123456") // {noop} 表示不加密(仅测试用!)
            .roles("ADMIN")
            .build();

        return new InMemoryUserDetailsManager(admin);
    }
}

⚠️ 注意:{noop} 表示密码明文存储!绝对不要在真实项目中使用,后面我会教你怎么加密。

第四步:启动并测试

  1. 启动应用
  2. 访问 http://localhost:8080 → 能直接看到首页
  3. 点击“进入管理后台” → 自动跳转到 Spring Security 默认登录页
  4. 输入用户名 admin,密码 123456 → 成功进入 /admin 页面!

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


新手常见问题 & 解决方案

问题现象 可能原因 解决方法
登录后还是跳回登录页 密码未加 {noop} 前缀 在密码前加上 {noop}(仅测试)
报错 There is no PasswordEncoder mapped... Spring Security 5+ 要求密码加密 使用 {noop} 或配置 BCryptPasswordEncoder
静态资源(CSS/JS)被拦截 未放行静态资源路径 authorizeHttpRequests 中加 .requestMatchers("/css/**", "/js/**").permitAll()
登录页样式丑 使用了默认登录页 可自定义 /login 页面,但需注意 CSRF token

🛠️ 避坑指南:我当初调试时,因为忘了加 {noop},折腾了两小时!记住:测试阶段用 {noop}密码,上线前必须换成加密方式!


下一步学习建议

你现在掌握了 Spring Security 的“骨架”,但真实项目远不止于此。建议按以下路径深入:

  1. 密码加密:学习 BCryptPasswordEncoder,替换 {noop}
  2. 数据库集成:用 JPAMyBatis 从数据库读取用户
  3. 角色与权限细化:区分 ROLE_ADMINROLE_USER,甚至细粒度权限(如 user:delete
  4. JWT 无状态认证:适合前后端分离项目(如 Vue + Spring Boot)
  5. OAuth2 / 微信登录:实现第三方登录

🌟 我已将本教程完整代码上传到 GitHub:https://github.com/yourname/spring-security-demo(记得替换为你的实际地址)。欢迎 Star & 提 Issue!


结语

Spring Security 初看复杂,但只要理解“认证 + 授权”的核心思想,再配合动手实践,你会发现它其实非常强大且灵活。不要怕配置,多试几次就熟了——我当初也是从一行行报错中走出来的。

如果你觉得这篇教程有帮助,欢迎关注我的 GitHub 技术博客,我会持续更新 Spring 系列实战内容。下期预告:《Spring Security + JWT 实现前后端分离登录》!

加油,未来的架构师!🚀

评论 0

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