LDAP用户授权失败:Spring认证出现未处理的Access is denied问题
看起来你已经解决了初始的LDAP角色读取错误(把ldap.grouprole.attribute从tc改成cn后,成功获取到了ROLE_MAKELAARS角色),现在的核心问题是权限规则没有匹配上已获取的角色,导致返回403。我来一步步帮你排查:
1. 确认当前认证状态(从你的日志可以看到)
你的日志已经明确显示:
09:04:40.553/20218 [catalina-exec-5] DEBUG o.s.s.l.u.DefaultLdapAuthoritiesPopulator - Roles from search: [Makelaars]
... Granted Authorities: ROLE_MAKELAARS
用户tc已经成功通过LDAP认证,并且拿到了ROLE_MAKELAARS角色,所以问题不在LDAP连接或用户认证环节,而是Spring Security的授权规则配置。
2. 修正权限访问规则配置
在你的WEB-INF/oeablSecurity.properties里,需要添加对应角色的授权规则,允许ROLE_MAKELAARS访问你的REST接口。比如:
# 允许MAKELAARS角色访问所有/api开头的接口(根据你的实际接口路径调整) http.authorize.requests=/api/**=hasRole('MAKELAARS')
注意:Spring Security的hasRole方法会自动给角色名称加上ROLE_前缀,所以配置里写MAKELAARS就对应日志里的ROLE_MAKELAARS。
如果你的接口有不同的权限需求,可以细化规则,比如:
# 公开登录接口 http.authorize.requests=/login=permitAll # 其他API需要MAKELAARS角色 http.authorize.requests=/api/**=hasRole('MAKELAARS') # 所有其他请求都需要认证 http.authorize.requests=/**=authenticated
3. 优化LDAP组搜索配置(可选)
当前你的ldap.groupsearch.base直接指定了单个组cn=Makelaars,ou=Groups,ou=Domain BPB,dc=bpb,dc=be,这意味着只会读取这个组的角色。如果未来需要支持多个组,建议把base改成组的根路径:
ldap.groupsearch.base=ou=Groups,ou=Domain BPB,dc=bpb,dc=be
这样ldap.groupsearch.filter=(member={0})会自动搜索所有包含当前用户的组,获取所有角色。
4. 检查控制器的安全注解(如果使用)
如果你的REST控制器方法上使用了@PreAuthorize或@Secured注解,要确保角色名称匹配:
- 使用
@PreAuthorize时,不需要加ROLE_前缀:@PreAuthorize("hasRole('MAKELAARS')") @GetMapping("/api/data") public ResponseEntity<?> getData() { // ... } - 使用
@Secured时,需要加上ROLE_前缀:@Secured("ROLE_MAKELAARS") @GetMapping("/api/data") public ResponseEntity<?> getData() { // ... }
5. 验证最终配置
修改完配置后,重启PAS实例,重新测试登录:
- 提交登录凭证后,应该能成功认证,并且正常返回REST接口的JSON响应
- 可以查看日志,确认授权环节是否通过,没有再出现403相关的错误
内容的提问来源于stack exchange,提问作者Antoon Verroken

