Spring Security 5.5 XML转Java配置后LDAP登录报AccessDeniedException
常见缺失配置项及修复方案
按照出现概率从高到低排序:
CSRF防护未适配或关闭
Spring Security 5.x默认开启CSRF防护,POST类型的登录请求如果未携带有效CSRF令牌会被直接拦截,返回匿名用户权限不足错误。
修复方案二选一:- 前后端不分离的表单登录在前端form标签内添加框架自动生成的CSRF隐藏参数即可
- 不需要CSRF防护的场景下,在
HttpSecurity配置中显式关闭:
@Override protected void configure(HttpSecurity http) throws Exception { http.csrf(csrf -> csrf.disable()); // 其余配置保持不变 }登录接口未放开匿名访问权限
如果授权规则配置顺序错误,或者未给/login相关路径放开访问权限,登录请求会被要求先认证,陷入死循环。
修复方案:
授权规则配置时优先放开登录相关路径,示例如下:http.authorizeHttpRequests(auth -> auth // 先放开登录页、登录请求、错误页、静态资源路径 .antMatchers("/login", "/login?error", "/css/**", "/js/**").permitAll() // 其余所有请求都需要认证 .anyRequest().authenticated() );FormLogin配置未绑定自定义扩展组件
你自定义的CustomWebAuthenticationDetailsSource、自定义成功/失败处理器如果未显式绑定到FormLogin配置中,不会生效,甚至会导致登录流程中断。
修复配置示例:http.formLogin(form -> form .loginPage("/login") // 显式指定登录请求处理路径,和前端提交的路径保持一致 .loginProcessingUrl("/login") // 绑定你自定义的AuthenticationDetailsSource .authenticationDetailsSource(customWebAuthenticationDetailsSource) .defaultSuccessUrl("/home", true) .failureUrl("/login?error") .permitAll() );LDAP认证提供者未正确注册到认证管理器
你的CustomUserDetailsContextMapper如果未绑定到LDAP认证提供者,或者LDAP认证提供者没有注册到全局AuthenticationManager中,登录请求会找不到对应的认证逻辑,默认校验不通过返回匿名身份。
修复配置示例:@Autowired public void configureLdapAuth(AuthenticationManagerBuilder auth, CustomUserDetailsContextMapper contextMapper) throws Exception { auth.ldapAuthentication() // 绑定自定义的UserContextMapper .userDetailsContextMapper(contextMapper) // 对应你原来XML的LDAP配置,比如用户DN规则、组搜索规则、上下文源等 .userDnPatterns("uid={0},ou=users") .groupSearchBase("ou=roles") .contextSource(ldapContextSource()); }全局方法安全注解未开启
如果原有XML开启了全局方法安全,Java配置需要显式添加@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)注解到你的安全配置类上,否则方法级权限校验逻辑异常会触发权限不足错误。
快速定位调试方案
如果上述配置都已正确配置,可在application.properties中开启Spring Security debug日志,查看请求在过滤器链中的拦截节点:
logging.level.org.springframework.security=DEBUG
内容的提问来源于stack exchange,提问作者Enuma Elish

