请写一篇关于【Spring Security基础:快速搭建安全认证系统】的技术文章

@杨志明
2025-12-19 03:43
阅读 647

去年十月,我被裁了。

那天是周三,下午三点。广州的秋天闷热得要命,老城区巷子里的老榕树叶子都蔫了。我在珠江新城那家SaaS公司干了三年半,本以为能安稳到年底拿年终奖,结果HR把我叫进会议室,递给我一杯冰美式,说“公司战略调整”。赔偿N+1,税后不到五万块。回家路上,我坐在地铁上,看着手机银行余额——3500房租还没交,老婆刚查出怀孕,而我的简历已经半年没更新了。

那一刻,我真的慌了。

但程序员嘛,慌归慌,手不能停。当晚我就开了台灯,在越秀老破小的阳台上搭了个临时工位,开始疯狂投简历。求职App刷到凌晨两点,Java岗清一色要求“熟悉微服务、精通Spring Security、有高并发经验”……我苦笑,之前项目里Security都是组长配好的,我连JWT怎么生成都没细看过。

从“Hello World”开始重建安全感

说实话,被裁之后我才真正意识到:技术债欠不得,尤其是安全这块。很多外包项目客户第一句就问:“登录安全怎么做?防不防CSRF?” 我要是答不上来,连报价的机会都没有。

于是我咬咬牙,用三天时间,从零搭了一个最简但完整的Spring Security认证系统。目标很明确:能跑、能登录、能保护接口、能对接数据库。不是为了炫技,是为了活下去。

第一步:加依赖,别整花活

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

很多人一上来就想搞OAuth2、JWT、多因子认证……打住!先让系统跑起来再说。我给自己定的规矩:先能用,再优化

第二步:UserDetails + UserDetailsService 是灵魂

我建了个User实体,对应数据库里的用户表。然后实现UserDetailsService

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

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepo.findByUsername(username);
        if (user == null) throw new UsernameNotFoundException("用户不存在");
        return org.springframework.security.core.userdetails.User
            .withUsername(user.getUsername())
            .password(user.getPassword()) // 注意:存的是BCrypt加密后的
            .roles("USER")
            .build();
    }
}

这里有个坑:密码必须是BCrypt加密的!我一开始直接存明文,本地测试没问题,一部署到测试环境就被客户骂了:“你们这系统能过等保吗?” 脸红得像荔枝。

第三步:配置SecurityFilterChain(Spring Boot 2.7+)

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable() // 前后端分离项目可暂时关掉,但生产环境建议开启并配Token
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin().disable() // 改用JSON登录
            .httpBasic().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        return http.build();
    }

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

这段代码我改了不下十遍。特别是.sessionManagement().sessionCreationPolicy(STATELESS),配合JWT才能做到无状态认证。但初期我连JWT都没上,先用Session过渡——因为快比完美重要

求职时,安全能力成了我的加分项

上个月,我去面一家做区块链供应链金融的初创公司。面试官是个Go语言出身的CTO,上来就问:“你们Java的安全框架是不是太重了?我们全栈Go,用Gin+Casbin,轻量又灵活。”

我坦白说:“Spring Security确实‘重’,但它稳。而且现在用Security 6.x + WebFlux,性能不输Go。” 然后我现场给他画了架构图:前端Vue → Spring Boot API → JWT Token → RBAC权限控制 → 区块链节点调用(通过Web3j)。

他眼睛一亮:“你还懂区块链调用?”

我说:“不懂底层,但会集成。上周刚帮一个客户把订单Hash上链,用的是阿里云BaaS平台。”

最后他没让我写Go,反而给了offer,月薪从15k谈到22k。他说:“我们需要能扛住安全审计的人,不是只会CRUD的。”

那一刻我明白了:技术栈不重要,解决问题的能力才值钱

外包路上的反思:别把自己局限在“Java程序员”

被裁后接的第一个外包项目,是个社区团购小程序。客户预算只有3万,要求三天上线。我硬着头皮用Spring Boot + Vue搭后台,但登录模块差点翻车——忘了配CORS,前端死活拿不到Set-Cookie。

后来我学乖了:小项目用现成方案。直接集成Sa-Token或者Shiro,省时省力。大项目才自己撸Security。

我也开始学Go。不是为了转行,而是理解不同生态的思路。比如Go的中间件模式,其实和Spring的Filter很像。区块链项目里,很多智能合约用Solidity,但后端服务用Go或Java调用,语言只是工具。

写给同样在路上的你

如果你也在焦虑、在投简历、在深夜debug,我想说:

  • 安全不是选修课,是生存技能。哪怕你只做业务开发,也得知道CSRF是什么、为什么密码不能明文存。
  • 别怕从基础做起。我35岁了,还在看Spring官方文档。技术更新快,但核心思想不变。
  • 跨界不是背叛,是进化。Java程序员可以学Go,也可以了解区块链。世界不会只围着你的舒适区转。

上周五晚上,我又接到一个新需求:帮一家跨境支付公司做KYC认证模块,要求符合GDPR。我打开IDEA,新建一个Spring Boot项目,pom.xml里敲下spring-boot-starter-security……

窗外,广州的夜雨淅淅沥沥。老婆在客厅织婴儿毛衣,锅里煲着老火汤。我知道,只要手还能敲代码,日子就塌不了。

共勉。

评论 0

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