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

林智
2025-12-29 14:45
阅读 2001

去年十月,我被裁了。

那天是周三,下午三点,刚开完一个需求评审会,HR把我叫进小会议室。她说“公司战略调整”,我点点头,心里却像被人狠狠踹了一脚。六年大厂经验,从Java初级干到后端TL,月薪22k,房租3500,和女朋友合租在浦东金桥——突然之间,一切悬在空中。

回家路上,地铁14号线挤得像沙丁鱼罐头。我盯着手机里猎聘上“急招Spring Security专家”的JD,苦笑。半年前我还觉得Security是“那种老掉牙的框架”,现在?它可能就是我下一份饭碗的关键。


别笑,真有人连Security都配不明白

上个月面试一个候选人,聊到权限控制,他张口就说:“我们用Shiro,轻量。” 我没戳破——其实他们项目根本没做RBAC,用户角色全靠if-else硬编码。这年头,很多所谓“微服务架构”,登录页还是/login?username=admin&password=123456

我自己也栽过跟头。三年前第一次接手一个遗留系统,前端传token,后端用自定义拦截器校验。结果某次上线,因为漏了@EnableWebSecurity,整个生产环境裸奔了48小时。CTO在晨会上冷笑:“你们这是给黑客发邀请函?”

Spring Security不是银弹,但它是底线。


快速搭个能跑的认证系统?三步走

别被官方文档吓到。我拿上周五晚上熬夜重构的一个demo举例(对,又是周五晚上,女朋友在隔壁打《原神》,我在Terminal里敲代码),核心就三块:

1. 引入依赖 + 启用Security

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

然后主类加注解:

@SpringBootApplication
@EnableWebSecurity
public class AuthApplication {
    public static void main(String[] args) {
        SpringApplication.run(AuthApplication.class, args);
    }
}

搞定。启动项目,访问任意接口,自动跳转到/login,默认用户名user,密码在控制台打印出来。虽然丑,但安全基线有了

2. 自定义UserDetails + UserDetailsService

真实项目不可能用内存用户。我一般建个UserDetailsServiceImpl

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found");
        }
        return org.springframework.security.core.userdetails.User
                .builder()
                .username(user.getUsername())
                .password(user.getPassword()) // 记得BCrypt加密!
                .roles(user.getRole().split(","))
                .build();
    }
}

开发心得: 密码千万别明文存!我见过实习生把MD5当“加密”,结果彩虹表一跑全露馅。直接用BCryptPasswordEncoder,Spring Security内置支持,一行配置:

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

3. 配置HttpSecurity —— 真正的战场

这才是面试题高频区。比如:“如何放行Swagger和健康检查接口?”

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable() // 前后端分离可关,但要知道风险
            .authorizeHttpRequests(authz -> authz
                .requestMatchers("/api/public/**", "/swagger-ui/**", "/actuator/health").permitAll()
                .requestMatchers("/api/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin().disable() // 用JWT就关掉表单登录
            .httpBasic().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        return http.build();
    }
}

面试题挑战来了:

  • CSRF为什么能关?
  • hasRole("ADMIN")hasAuthority("ROLE_ADMIN") 有啥区别?
  • 如何实现动态权限(比如从数据库读菜单权限)?

答不上来?回去看源码。DefaultWebSecurityExpressionHandler里藏着答案。


别只盯着Java,Go也在抢饭碗

说到这个,我最近在学Go。倒不是想转语言栈,而是发现很多新项目——尤其是云原生、边缘计算场景——直接用Go写Auth服务。Gin + JWT + Casbin,性能吊打Spring Boot。

上周和前同事吃饭,他在一家做IoT的 startup,后端全Go。他说:“你们Java搞个Security配置半小时,我们main.go 50行搞定,还省了JVM内存。”

我嘴上不服:“Go的生态能比Spring全家桶?”
心里却慌了。毕竟裁员名单不分语言。

现实很骨感: 大厂Java岗还在招,但要求越来越高。不仅要你会Security,还要懂OAuth2.0、OIDC、多租户隔离、甚至零信任架构。上周面阿里P7,面试官直接问:“如果让你设计一个支持万级租户的权限中心,怎么保证性能?”


从焦虑到行动:我的自救路线

被裁后那两周,我天天刷LeetCode,但越刷越慌。后来想通了:与其死磕算法,不如把工程能力打扎实。

我做了三件事:

  1. 重写了一个RBAC demo:用Spring Security + JWT + Redis缓存权限,代码开源在GitHub(Star 120+,虽然不多,但至少证明我能跑通)
  2. 啃了《Spring Security in Action》:英文原版,边看边骂作者啰嗦,但第9章讲Method Security那段救了我命
  3. 模拟面试:找朋友扮演面试官,专问Security细节。比如:“FilterChain执行顺序怎么排?UsernamePasswordAuthenticationFilter在哪个位置?”

上个月拿到offer,月薪25k,涨了3k。谈薪时我说:“我不仅会写CRUD,还能守住安全底线。” HR笑了:“现在能配明白Security的人,确实不多。”


最后说点人话

技术人总爱追新:Service Mesh、Dapr、WASM……但别忘了,系统的地基永远是身份认证和权限控制。你用再炫的框架,登录页被爆破,数据全丢,老板照样让你卷铺盖。

Spring Security难吗?难。文档反人类,配置像迷宫。但它值得你花时间。因为它不只是一个框架,而是一种安全思维——知道什么该放行,什么必须拦住,什么需要二次确认。

就像我和女朋友合租,门禁卡她一把,我一把;但她支付宝密码?打死不给。(开玩笑,其实是她不给我看)


给正在挣扎的你

如果你也刚被裁,或者在面试中被Security问题问懵,别慌。我经历过:

  • 凌晨三点改配置,结果忘了关CSRF,本地能跑线上500
  • antMatchers写成requestMatchers,Spring Boot 3升级踩坑
  • 被问“Security底层原理”时大脑空白,只能背八股文

但这些都不丢人。真正的工程师,是在烂泥里也能搭出安全围栏的人。

未来我会继续学Go,不是为了抛弃Java,而是理解不同语言的安全模型。也许明年,我会写《Go中的Casbin实战》,但今天,我依然相信:掌握Spring Security,是你作为Java后端不可妥协的基本功。

共勉。

(写完这篇,女朋友喊我吃宵夜。她说:“你再不关电脑,我就拔电源了。” 得,安全系统再强,也防不住枕边人啊。)

评论 0

最热最新
暂无评论
林智Lv.1
0
影响力
0
文章
0
粉丝