零基础也能搞懂:用Spring Security快速搭建登录认证系统

熔断背锅人
2026-01-05 04:40
阅读 2094

大家好,我是一名从培训班出来的前端开发者,但因为在工作中经常和后端打交道,也踩过不少Spring Security的坑。当初我第一次接触“安全认证”这种词时,脑子里全是问号:什么是认证?为什么我的接口随便就能被调用?用户密码怎么存才安全?后来我才明白,任何需要用户登录的系统,都离不开安全框架的保护

今天这篇文章,就是写给和我当年一样——完全零基础、连Java项目都没跑起来过的新手朋友。别担心,我会用最直白的语言,带你一步步用 Spring Security 搭建一个带用户名密码登录的安全系统。对了,虽然标题提到了 Go 和 Python,但咱们主讲 Java 的 Spring Security(毕竟它是 Java 生态最主流的安全框架)。不过我会在文末告诉你,Go 和 Python 里类似的东西叫什么,方便你未来拓展。


一、Spring Security 是啥?能干啥?

简单说:Spring Security 就是给你的 Web 应用上把“锁”

  • 没有它:任何人打开 http://localhost:8080/admin 都能看到后台页面
  • 有了它:只有登录过的管理员才能进,别人会被自动跳转到登录页

它能帮你自动处理:

  • 用户登录(表单、手机号、第三方等)
  • 密码加密存储
  • 权限控制(比如普通用户不能删数据)
  • 防止 CSRF、XSS 等常见攻击

💡 小知识:虽然 Go 有 Gin + JWTCasbin,Python 有 Django AuthFlask-Login,但如果你在 Java 世界,Spring Security 几乎是唯一选择。


二、环境准备:5分钟搭好开发工具

我们不需要复杂配置!只需以下三样:

工具 版本建议 作用
JDK 17 或 21 Java 运行环境
IntelliJ IDEA 社区版免费 写代码的编辑器
Maven 内置在 IDEA 中 项目依赖管理工具

步骤 1:创建 Spring Boot 项目

  1. 打开 https://start.spring.io
  2. 选择:
    • Project: Maven
    • Language: Java
    • Spring Boot: 3.2.x
    • Dependencies: 勾选 Spring WebSpring Security

✅ 我当初学的时候,直接在 IDEA 里点 “New Project → Spring Initializr” 也能做到,更方便!

步骤 2:导入项目并启动

下载 zip 包 → 解压 → 用 IDEA 打开 → 等待 Maven 下载依赖(首次较慢)→ 运行 DemoApplication.java

启动成功后,访问 http://localhost:8080 —— 你会被自动跳转到一个丑丑的登录页!用户名是 user,密码在控制台打印出来了(类似 Using generated security password: abc123...)。

⚠️ 注意:这个默认登录页只是演示,我们马上替换成自己的!


三、核心概念:用大白话讲清楚

新手最容易被这些词吓住,其实很简单:

1. 认证(Authentication)

“你是谁?”
比如用户输入用户名 alice 和密码 123456,系统验证是否正确。

2. 授权(Authorization)

“你能干什么?”
比如 alice 是普通用户,只能看数据;admin 才能删除数据。

3. 密码加密(不是明文!)

绝对不要存 123456!要用算法加密。
Spring Security 默认用 BCrypt 算法 —— 它是一种不可逆的哈希算法,就算数据库泄露,黑客也很难破解原密码。

🤔 算法小科普:BCrypt 属于“慢哈希算法”,故意算得慢,防止暴力破解。Go 里有 golang.org/x/crypto/bcrypt,Python 有 bcrypt 库,原理一样。


四、实战:5步打造自定义登录系统

目标:实现一个 /hello 接口,只有登录用户才能访问。

第 1 步:写个简单 Controller

// src/main/java/com/example/demo/HelloController.java
package com.example.demo;

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

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, you are authenticated!";
    }
}

第 2 步:配置 Security(关键!)

新建配置类:

// src/main/java/com/example/demo/SecurityConfig.java
package com.example.demo;

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 InMemoryUserDetailsManager userDetailsService() {
        // 创建一个内存中的用户(仅用于演示!)
        UserDetails user = User.builder()
                .username("alice")
                .password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW") // 密码是 "123456"
                .roles("USER")
                .build();
        return new InMemoryUserDetailsManager(user);
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/hello").authenticated()  // /hello 需要登录
                .anyRequest().permitAll()                   // 其他路径放开
            )
            .formLogin(form -> form
                .loginPage("/login")        // 自定义登录页(可选)
                .permitAll()
            )
            .logout(logout -> logout.permitAll());
        return http.build();
    }
}

🔑 重点解释

  • {bcrypt}... 是提前用 BCrypt 加密好的 123456
  • InMemoryUserDetailsManager 表示用户存在内存里(生产环境要用数据库!)
  • authorizeHttpRequests 定义哪些路径需要认证

第 3 步:生成加密密码(工具推荐)

你不可能记住那一长串哈希值!可以用这个小工具生成:

// 临时测试类,运行一次即可
public class PasswordEncoderUtil {
    public static void main(String[] args) {
        System.out.println("{bcrypt}" + new BCryptPasswordEncoder().encode("123456"));
    }
}

或者用在线工具(搜索 “BCrypt online generator”),但切勿在生产环境用在线工具处理真实密码!

第 4 步:测试效果

  1. 启动项目
  2. 访问 http://localhost:8080/hello
  3. 自动跳转到 Spring Security 默认登录页
  4. 输入用户名 alice,密码 123456
  5. 成功看到 Hello, you are authenticated!

第 5 步:自定义登录页(可选但实用)

新建 src/main/resources/templates/login.html(需引入 Thymeleaf):

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>Login</title></head>
<body>
  <form th:action="@{/login}" method="post">
    <input type="text" name="username" placeholder="用户名" required />
    <input type="password" name="password" placeholder="密码" required />
    <button type="submit">登录</button>
  </form>
</body>
</html>

并在 pom.xml 加依赖:

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

重启后,登录页就变成你自己的了!


五、新手常见问题解答

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

A:Spring Security 需要知道用哪种算法解密。{bcrypt} 是一个前缀标识,告诉框架“后面这段是 BCrypt 加密的”。

Q2:用户能不能存数据库?

A:当然可以!但需要实现 UserDetailsService 接口,从数据库查用户。这是下一步要学的内容。

Q3:为什么不用 Go 或 Python 做这个?

A:如果你公司用 Java 技术栈,Spring Security 是最佳选择。Go 更适合高并发微服务,Python 适合快速原型。工具要匹配场景

Q4:这个安全吗?

A:基础功能是安全的,但生产环境还需:

  • HTTPS
  • 防暴力破解(限制登录次数)
  • 使用 JWT 替代表单登录(适合前后端分离)

六、学习建议:下一步怎么走?

  1. 先掌握基础:确保你能独立写出上面的代码
  2. 连接数据库:学习 JPA + UserDetailsService,把用户存进 MySQL
  3. 了解 JWT:前后端分离项目常用,替代 session
  4. 横向对比
    • Go:学 Gin + JWT + Casbin
    • Python:学 Djangoauth 模块或 FastAPI + OAuth2
  5. 深入算法:理解 BCrypt、PBKDF2、Argon2 等密码哈希算法的区别

💬 最后说一句:我当初学 Spring Security 时,光是“过滤器链”就懵了三天。但只要你动手敲代码,从最简单的例子开始,很快就能上手。安全不是魔法,而是一步步配置出来的

现在,去你的 IDE 里新建一个项目,跑通这个例子吧!遇到问题,欢迎回来再读一遍 😄

评论 0

最热最新
暂无评论
熔断背锅人Lv.1
0
影响力
0
文章
0
粉丝