从培训班出来后,我用Spring Security搭了个登录系统

全栈手艺人
2026-01-06 04:28
阅读 1229

大家好,我是老张,一个从培训班毕业、如今在一线做后端开发的“野生程序员”。当初我刚学Java那会儿,听到“Spring Security”这名字就头大——又是Security,又是认证授权,感觉高深莫测。后来面试被问到,支支吾吾答不上来,吃了不少亏。

今天我就用最接地气的方式,手把手带你用Spring Boot快速搭建一个带登录认证的安全系统。不讲虚的,全是实战经验,连我踩过的坑都会告诉你!


为什么你需要Spring Security?

想象一下:你做了一个博客系统,任何人都能删别人的文章?或者后台管理页面,随便输入网址就能进?这显然不行!

Spring Security 就是Spring生态里专门负责“守门”的组件。它能帮你:

  • 控制谁可以访问哪些页面(比如:只有管理员能进后台)
  • 实现用户名密码登录
  • 防止跨站请求伪造(CSRF)、暴力破解等攻击
  • 和JWT、OAuth2等高级安全机制集成

💡 我当初以为安全就是加个登录框,结果上线后被黑客刷接口,差点背锅!后来才知道,安全不是功能,而是基础设施。


环境准备:5分钟搭好开发环境

我们用 Java + Spring Boot 作为后端,前端暂时用最简单的 HTML + JavaScript(后面会说明为什么不直接用Vue/React)。

所需工具清单

工具 版本建议 作用
JDK 17 或 21 Java运行环境
Maven 3.8+ 项目依赖管理
IDE IntelliJ IDEA(社区版免费) 写代码
浏览器 Chrome / Edge 测试登录

✅ 提醒:别用JDK 8了!虽然还能跑,但Spring Boot 3.x 起最低要求JDK 17,早点升级省得以后迁移麻烦。

创建项目(两种方式)

方式一:用 Spring Initializr(推荐新手)

访问 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打开即可。

方式二:手动加依赖(了解原理)

如果你已有项目,在 pom.xml 中加入:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

⚠️ 注意:Spring Boot 3.x 默认使用 Jakarta EE 9+,包名从 javax.* 变成了 jakarta.*,别写错!


核心概念:Security到底在干啥?

很多教程一上来就讲“认证 vs 授权”,太抽象。我用快递站打个比方:

  • 认证(Authentication):你拿身份证证明“你是张三” → 相当于登录
  • 授权(Authorization):快递员看你是不是收件人,决定给不给你包裹 → 相当于权限控制

Spring Security 的工作流程像这样:

用户请求 → Security拦截 → 检查是否登录?
                ↓ 是
          检查有没有权限?
                ↓ 是
            放行,执行业务逻辑
                ↓ 否
            返回403错误
                ↓ 否(未登录)
            跳转到登录页

默认情况下,只要你引入 spring-boot-starter-security所有接口都会被保护!启动项目后访问任意URL,会被自动跳到 /login 页面,并且用户名是 user,密码在控制台打印(每次启动都不同)。

🤯 我第一次看到控制台输出 Using generated security password: xxxxx 时,还以为被黑了!


实战:搭建一个带自定义登录页的系统

目标:实现一个简单的后台,只有登录后才能访问 /admin 页面。

第一步:创建控制器

// 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 "home"; // 返回 home.html
    }

    @GetMapping("/admin")
    public String admin() {
        return "admin"; // 返回 admin.html
    }

    @GetMapping("/login")
    public String login() {
        return "login"; // 自定义登录页
    }
}

第二步:写前端页面(Thymeleaf模板)

src/main/resources/templates/ 下创建三个文件:

home.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>首页</title>
</head>
<body>
    <h1>欢迎来到首页!</h1>
    <a th:href="@{/admin}">进入后台</a>
    <br/>
    <a th:href="@{/logout}">退出登录</a>
</body>
</html>

admin.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>后台管理</title>
</head>
<body>
    <h1>这是受保护的后台页面!</h1>
    <a th:href="@{/}">返回首页</a>
</body>
</html>

login.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>登录</title>
</head>
<body>
    <h2>用户登录</h2>
    
    <!-- 错误提示 -->
    <div th:if="${param.error}" style="color:red;">
        用户名或密码错误!
    </div>
    
    <!-- 登出成功提示 -->
    <div th:if="${param.logout}" style="color:green;">
        您已成功退出!
    </div>

    <form th:action="@{/login}" method="post">
        <div>
            <label>用户名: <input type="text" name="username" /></label>
        </div>
        <div>
            <label>密码: <input type="password" name="password" /></label>
        </div>
        <button type="submit">登录</button>
    </form>
</body>
</html>

🔍 注意:表单字段名必须是 usernamepassword!这是Spring Security默认的参数名。

第三步:配置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(auth -> auth
                .requestMatchers("/", "/login").permitAll() // 首页和登录页公开
                .anyRequest().authenticated()               // 其他所有请求需要登录
            )
            .formLogin(form -> form
                .loginPage("/login")        // 自定义登录页
                .defaultSuccessUrl("/admin") // 登录成功跳转
                .permitAll()
            )
            .logout(logout -> logout
                .permitAll()
            );
        return http.build();
    }

    // 内存中创建用户(仅用于演示!)
    @Bean
    public InMemoryUserDetails

评论 0

最热最新
暂无评论
全栈手艺人Lv.1
0
影响力
0
文章
0
粉丝