Spring Security基础:快速搭建安全认证系统(零基础入门实战)

独立开发路上
2025-12-13 09:38
阅读 310

大家好,我是一名从培训班出来的前端转全栈开发者。虽然现在主要做后端开发,但我至今记得当初刚学 Java 时面对 Spring Security 一脸懵的样子——文档又厚、概念又多,光是“认证”和“授权”就绕晕了。更别说面试官一句:“你会 Spring Security 吗?”直接让我求职路上吃了不少亏。

所以今天,我就以一个过来人的身份,用最直白的话、最少的术语、最多的代码示例,带你从零开始搭一个能跑的安全认证系统。哪怕你连 Maven 是啥都不清楚,只要会写 Hello World,这篇教程就能让你上手 Spring Security,并在简历上自信地写上“熟悉 Spring 安全框架”。


一、Spring Security 是什么?为什么求职必须会?

简单说:Spring Security 就是给你的 Java Web 应用装一把“智能门锁”

  • 没有它:任何人输入 http://localhost:8080/admin 都能进后台。
  • 有了它:只有登录过的用户才能访问,管理员才能进 /admin,普通用户只能看首页。

在企业级项目中,权限控制是刚需。无论是电商、OA 系统还是后台管理平台,都离不开用户登录、角色判断、接口保护等功能。而 Spring Security 正是 Spring 生态中最主流、最强大的安全框架。

💡 求职提示:我在面试 10+ 家公司时,9 家都问到了 Spring Security。哪怕你只做过 Demo,只要能讲清楚流程,就能加分!


二、环境准备(手把手教你配好开发环境)

别担心,我们用最简单的组合:

工具 版本建议 说明
JDK 17 或 11 推荐 JDK 17(LTS)
IDE IntelliJ IDEA 社区版免费够用
构建工具 Maven Spring Boot 默认集成
依赖管理 Spring Boot 3.x 注意:3.x 要求 JDK ≥17

步骤 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 打开。

✅ 我当初学的时候,连依赖都不会选,结果漏了 Thymeleaf,页面一直 404,折腾半天才发现……


三、核心概念:用大白话解释专业术语

很多教程一上来就讲 AuthenticationManagerUserDetailsService,新手直接劝退。其实你只需要先理解这三个词:

1. 认证(Authentication) → “你是谁?”

  • 用户输入用户名 + 密码
  • 系统验证是否正确
  • 正确 → 登录成功;错误 → 提示密码错误

2. 授权(Authorization) → “你能干什么?”

  • 登录后,系统检查你的“身份标签”(比如 ROLE_ADMIN)
  • 访问 /admin 时,只有带 ROLE_ADMIN 标签的人才能进

3. SecurityFilterChain → “安全规则总开关”

  • 这是你写规则的地方:哪些路径要登录?哪些公开?
  • 比如:/login 公开,/user/** 必须登录,/admin/** 必须是管理员

🧠 类比理解
认证 = 刷身份证进门
授权 = 保安看你工牌决定能不能进机房
SecurityFilterChain = 大楼的门禁规则表


四、实战项目:5 分钟搭一个登录系统

我们现在要做一个超简单的系统:

  • 首页 /:所有人可访问
  • 用户页 /user:必须登录
  • 管理员页 /admin:必须是 ADMIN 角色
  • 登录页:Spring Security 自带(先用默认的)

第一步:启动项目,看看默认效果

  1. 打开 SecurityDemoApplication.java,确保有 @SpringBootApplication
  2. 右键运行 main 方法
  3. 浏览器访问 http://localhost:8080

你会发现:自动跳转到 /login 页面!

这是 Spring Security 的默认行为:所有请求都被拦截,必须登录

🔑 默认用户名:user
默认密码:启动日志里找(类似 Using generated security password: abc123...

试着用这个账号登录,成功后访问 /user,你会发现 404 —— 因为我们还没写页面!


第二步:创建页面(用 Thymeleaf)

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

home.html(首页)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>首页</title></head>
<body>
  <h1>欢迎来到首页!</h1>
  <p><a th:href="@{/user}">去用户页</a></p>
  <p><a th:href="@{/admin}">去管理员页</a></p>
  <form th:action="@{/logout}" method="post">
    <button type="submit">退出登录</button>
  </form>
</body>
</html>

user.html(用户页)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head><title>用户页</title></head>
<body>
  <h1>用户专属页面</h1>
  <p>只有登录用户才能看到这里!</p>
  <a th:href="@{/}">返回首页</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 th:href="@{/}">返回首页</a>
</body>
</html>

第三步:写 Controller 路由

创建 WebController.java

package com.example.securitydemo;

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

@Controller
public class WebController {

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

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

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

现在重启项目,访问 / → 成功显示首页!

但点击“去用户页”,还是会跳回登录页?因为 Spring Security 默认 所有路径都需要认证


第四步:配置 Security 规则(重点!)

创建配置类 SecurityConfig.java

package com.example.securitydemo;

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("/", "/home").permitAll()     // 首页公开
                .requestMatchers("/user").authenticated()      // 用户页需登录
                .requestMatchers("/admin").hasRole("ADMIN")    // 管理员页需 ADMIN 角色
                .anyRequest().authenticated()                  // 其他所有请求都要登录
            )
            .formLogin(form -> form
                .loginPage("/login")          // 使用默认登录页(Spring Security 自动生成)
                .permitAll()
            )
            .logout(logout -> logout
                .permitAll()
            );
        return http.build();
    }

    // 内存中定义两个用户(仅用于演示!)
    @Bean
    public InMemoryUserDetailsManager userDetailsService() {
        UserDetails user = User.withDefaultPasswordEncoder()
            .username("zhangsan")
            .password("123456")
            .roles("USER")
            .build();

        UserDetails admin = User.withDefaultPasswordEncoder()
            .username("lisi")
            .password("123456")
            .roles("ADMIN")
            .build();

        return new InMemoryUserDetailsManager(user, admin);
    }
}

⚠️ 注意:User.withDefaultPasswordEncoder() 仅用于学习!生产环境必须用 BCryptPasswordEncoder


第五步:测试功能

重启应用,尝试以下操作:

用户名 密码 能访问哪些页面?
zhangsan 123456 首页、用户页 ✅;管理员页 ❌
lisi 123456 首页、用户页、管理员页 ✅

完美!一个带角色控制的认证系统就完成了。


五、新手常见问题 & 解决方案

❓ 问题 1:为什么登录后总是跳回首页,而不是我原本想访问的页面?

原因:Spring Security 默认登录成功后重定向到 /

解决:在 formLogin 中添加 .defaultSuccessUrl("/user", true)

  • 第二个参数 true 表示总是跳转到指定页
  • 设为 false 则会跳回之前想访问的页面
.formLogin(form -> form
    .loginPage("/login")
    .defaultSuccessUrl("/user", false) // 推荐设为 false
    .permitAll()
)

❓ 问题 2:怎么自定义登录页面?

  1. 创建 login.html
<form th:action="@{/login}" method="post">
  用户名: <input type="text" name="username"><br>
  密码: <input type="password" name="password"><br>
  <button type="submit">登录</button>
</form>
  1. 在 SecurityConfig 中指定:
.formLogin(form -> form
    .loginPage("/login")      // 自定义登录页路径
    .permitAll()
)
  1. 在 Controller 中加路由:
@GetMapping("/login")
public String login() {
    return "login";
}

✅ 我当初死活不知道 name="username"name="password" 是固定的字段名,改了就登录失败……


❓ 问题 3:密码明文存储太危险,怎么加密?

替换 userDetailsService() 中的密码编码方式:

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

@Bean
public InMemoryUserDetailsManager userDetailsService() {
    PasswordEncoder encoder = passwordEncoder();
    UserDetails user = User.builder()
        .username("zhangsan")
        .password(encoder.encode("123456")) // 加密存储
        .roles("USER")
        .build();
    // ...其他用户
}

🔐 永远不要在代码里写明文密码!面试官看到直接扣分。


六、学习建议 & 下一步方向

你现在已经有能力做出一个带角色控制的登录系统了!这已经超过了 60% 的培训班同学。接下来:

✅ 短期目标(求职前必做)

  1. 把内存用户换成数据库(用 JPA + UserDetailsService
  2. 加上“记住我”功能.rememberMe()
  3. 处理登录失败、登出后的跳转
  4. 用 Postman 测试接口权限(为做 API 安全打基础)

📚 推荐学习路径

Spring Security 基础 → 数据库存储用户 → JWT Token 认证 → OAuth2(微信/Google登录)→ 微服务安全(Spring Cloud Gateway + Auth)

💼 求职技巧

  • 在简历写:“使用 Spring Security 实现基于角色的访问控制(RBAC)”
  • 准备一句话解释流程:“用户请求 → Security 过滤器链拦截 → 认证 → 授权 → 放行或拒绝”
  • 如果被问到细节,就说:“我用过内存用户和数据库用户,知道如何自定义登录页和权限规则”

最后说两句

我当初学 Spring Security 时,被各种抽象概念折磨得想放弃。但后来发现:只要先跑通一个 Demo,再逐步替换组件,根本没那么难

这篇文章里的代码,你完全可以复制粘贴跑起来。跑通了,你就战胜了 80% 的观望者。技术学习最怕“只看不练”,现在就去敲一遍吧!

祝你在 Java 求职路上少走弯路,早日拿到 offer!如果有问题,欢迎留言讨论 👨‍💻

评论 0

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