零基础也能上手:用 Spring Security 快速搭建安全认证系统

马秀英_技术达人
2025-12-22 22:19
阅读 1686

大家好,我是小林,一名 211 高校的计算机专业研究生。平时我喜欢写技术博客,尤其爱帮刚入门的新朋友理清那些“看起来高大上”的框架。今天这篇教程,就是因为我当初学 Spring Security 时踩过太多坑——文档复杂、概念抽象、配置繁琐,差点让我放弃后端开发!

所以,我想用最通俗的方式,带你从零开始搭建一个带登录认证的安全系统。哪怕你连“什么是认证”都不清楚,也没关系。咱们一步步来。

顺便说一句:虽然标题里提到了 Go 和运营,但本文聚焦 Java 生态的 Spring Security。为什么?因为很多创业公司或传统企业后台仍以 Java 为主,而 Go 虽然在微服务和高并发场景很火,但在快速搭建企业级权限系统方面,Spring Security 的生态更成熟。至于“运营”,其实任何系统的安全都离不开权限控制——比如运营人员只能看数据,不能删用户,这正是我们要解决的问题。


一、Spring Security 是什么?

简单说:它是一个帮你自动处理“谁可以访问什么”的工具包

想象一下:

  • 用户没登录,却想进后台管理页?→ 拦住!
  • 普通用户想删除别人的文章?→ 不行!
  • 运营人员只能看报表,不能改配置?→ 安排!

这些规则,不用你一行行写 if-else 判断,Spring Security 帮你搞定。


二、环境准备(5 分钟搞定)

你需要以下工具:

工具 版本建议 说明
JDK 17 或 21 推荐使用 LTS 版本
Maven 3.8+ 项目依赖管理
IDE IntelliJ IDEA 免费社区版即可
Spring Boot 3.x 我们基于最新稳定版

创建项目

  1. 打开 Spring Initializr

  2. 选择:

    • Project: Maven
    • Language: Java
    • Spring Boot: 3.2.x
    • Dependencies: 勾选 Spring WebSpring Security
  3. 点击 “Generate” 下载 ZIP,解压后用 IDEA 打开。

✅ 小贴士:我当初第一次创建时忘了加 Security 依赖,结果访问 /login 页面报 404,折腾半天才发现漏了这步!


三、核心概念:认证 vs 授权

很多新手分不清这两个词,其实很简单:

  • 认证(Authentication):你是谁?→ 比如输入用户名密码登录。
  • 授权(Authorization):你能干什么?→ 比如只有管理员能删用户。

Spring Security 默认会:

  • 自动生成一个随机密码(启动日志里能看到)
  • 拦截所有请求,要求先登录
  • 提供一个简单的登录页面(/login

我们先跑起来看看!


四、实战:5 步搭建基础认证系统

第 1 步:写一个测试接口

src/main/java/com/example/demo 下新建 HelloController.java

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

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

第 2 步:启动项目

运行 DemoApplication.main(),控制台会输出类似:

Using generated security password: a1b2c3d4-e5f6-...

这个就是默认密码!用户名是 user

第 3 步:访问试试

  1. 浏览器打开 http://localhost:8080/hello
  2. 自动跳转到 /login
  3. 输入:
    • Username: user
    • Password: 控制台打印的那个随机串
  4. 登录成功,看到 "Hello, you are authenticated!"

🔒 注意:每次重启应用,密码都会变!这只是开发临时方案。

第 4 步:自定义用户名密码(别再用随机密码了!)

新建配置类 SecurityConfig.java

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails user = User.builder()
                .username("operator")      // 运营账号
                .password("{noop}123456") // {noop} 表示不加密(仅测试用!)
                .roles("USER")
                .build();

        UserDetails admin = User.builder()
                .username("admin")
                .password("{noop}admin123")
                .roles("ADMIN")
                .build();

        return new InMemoryUserDetailsManager(user, admin);
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/hello").hasRole("USER")     // 运营和管理员都能访问
                .requestMatchers("/admin").hasRole("ADMIN")    // 只有管理员能访问
                .anyRequest().authenticated()                  // 其他请求都要登录
            )
            .formLogin(form -> form
                .loginPage("/login")        // 使用默认登录页
                .permitAll()                // 登录页不需要认证
            )
            .logout(logout -> logout.permitAll());

        return http.build();
    }
}

现在你可以用:

  • operator / 123456 → 访问 /hello,但访问 /admin 会被拒
  • admin / admin123 → 两个都能访问

第 5 步:理解关键代码

  • UserDetailsService:定义用户从哪来(这里用内存存储,生产环境要用数据库)
  • hasRole("ADMIN"):自动加上前缀 ROLE_,所以实际权限是 ROLE_ADMIN
  • {noop}:表示明文密码。生产环境必须用 BCrypt 加密!

五、新手常见问题解答

Q1:为什么页面跳转到 /login 但显示白页?

A:Spring Boot 3 默认不提供 Thymeleaf 模板。如果你只想用 JSON API,可以禁用表单登录:

.formLogin(login -> login.disable())
.httpBasic(withDefaults()) // 改用 HTTP Basic 认证

这样前端用 Authorization: Basic base64(username:password) 请求即可。

Q2:如何把用户存在数据库里?

A:只需替换 UserDetailsService 实现:

@Service
public class MyUserDetailsService implements UserDetailsService {
    @Autowired
    private UserRepository userRepo;

    @Override
    public UserDetails loadUserByUsername(String username) {
        UserEntity user = userRepo.findByUsername(username);
        if (user == null) throw new UsernameNotFoundException("...");
        return org.springframework.security.core.userdetails.User
                .builder()
                .username(user.getUsername())
                .password(user.getPassword()) // 数据库存的是 BCrypt 密文
                .roles(user.getRole())
                .build();
    }
}

记得密码要用 BCryptPasswordEncoder 加密存储!

Q3:和 Go 的 Gin/JWT 方案比,哪个更好?

对比项 Spring Security Go + JWT
学习曲线 较陡(概念多) 平缓
开发速度 快(自动防护) 需手动实现
适用场景 企业后台、OA 系统 API 服务、微服务
运营支持 角色/权限粒度细 需自行设计

如果你要做一个给运营团队用的管理系统,Spring Security 更省心;如果做对外 API,Go + JWT 更轻量。


六、下一步学习建议

  1. 加密密码:去掉 {noop},改用 BCryptPasswordEncoder
  2. 集成数据库:用 JPA 或 MyBatis 存储用户
  3. 前后端分离:返回 JSON 而非跳转页面
  4. JWT 支持:适合移动端或单页应用
  5. OAuth2:接入微信/Google 登录

💡 我的建议:先掌握基础表单认证,再学 JWT。不要一上来就搞复杂方案!


结语

Spring Security 看似复杂,但核心思想就两点:认人(认证)+ 管权限(授权)。今天我们用不到 100 行代码,就实现了一个带角色区分的安全系统,连运营人员的访问边界都划好了。

记住:安全不是功能,而是底线。哪怕你的系统再小,也该有基本的防护。

如果你觉得这篇教程帮到了你,欢迎留言告诉我你的实践过程!也欢迎关注我的博客,我会持续更新“让新手少走弯路”的实战指南。

加油,未来的后端工程师!🚀

评论 0

最热最新
暂无评论
马秀英_技术达人Lv.1
0
影响力
0
文章
0
粉丝