SpringBoot集成SpringSecurity时springSecurityFilterChain创建失败求助
问题定位与解决方案
嘿,我一眼就揪出你遇到的问题根源啦!
错误原因
从报错信息里的 java.lang.IllegalArgumentException: key cannot be empty or null 就能精准定位:问题出在你Spring Security配置的记住我(rememberMe)功能上。
在你的WebSecurityConfig类中,你写了 .key("") —— 这里传入的是空字符串,但Spring Security要求这个key必须是非空的,它是用来加密remember-me令牌的核心密钥,绝对不能为空或null。
修复步骤
只需要修改WebSecurityConfig里的rememberMe配置,把空key替换成一个有实际内容的自定义字符串即可,示例如下:
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() // 重要提醒:权限规则要把更具体的路径放在前面,否则/**会覆盖/admin/**的规则 .antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')") .antMatchers("/**").access("hasRole('ROLE_USER')") .anyRequest().authenticated().and() // 替换成自定义的安全密钥,建议用复杂且唯一的字符串 .rememberMe().tokenValiditySeconds(60 * 60 * 24 * 7).key("mySecureRememberMeKey_2024").and() .formLogin().loginPage("/login").failureUrl("/login?error").permitAll().and() .logout().permitAll(); }
额外优化建议
- 权限规则顺序问题:你原来的配置先写了
/**的规则,再写/admin/**,这样/admin/**的规则永远不会生效,因为/**已经匹配了所有路径。一定要把更具体的路径规则放在前面,就像上面修改后的代码那样。 - 生产环境密钥管理:如果是生产环境,别把密钥硬编码在代码里,建议放在配置文件中:
然后在配置类中注入使用:# application.properties security.remember-me.key=yourSuperSecureUniqueKeyHere@Value("${security.remember-me.key}") private String rememberMeKey; // 在configure方法中替换key参数 .rememberMe().tokenValiditySeconds(60 * 60 * 24 * 7).key(rememberMeKey).and() - 密码加密安全:注意到你在
CustomUserService中直接返回了用户原始密码user.getPwd(),生产环境中这是极大的安全隐患!Spring Security要求密码必须加密处理,建议使用BCryptPasswordEncoder:- 在
WebSecurityConfig中添加密码编码器Bean:@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } - 配置认证时关联编码器:
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(customUserService()).passwordEncoder(passwordEncoder()); } - 确保数据库中存储的是BCrypt加密后的密码字符串,而非明文。
- 在
内容的提问来源于stack exchange,提问作者Julius Wang
相关产品推荐
相关产品推荐

