Spring Boot集成Keycloak Bearer-only模式后端服务无法正常工作
嘿,我之前帮不少开发者排查过类似的Keycloak整合问题,你遇到的前端正常但调用后端报错的情况,大概率是跨域(CORS)配置遗漏或者Token传递/验证环节出了问题,结合你的配置,咱们一步步来排查解决:
一、先确认前端请求是否正确带了Token
Angular端用Keycloak的话,应该是用了keycloak-angular适配器吧?你得确保调用后端API时,请求头里确实带上了Authorization: Bearer <你的访问令牌>。
你可以打开浏览器的Network面板,找到调用后端的请求,查看Request Headers里有没有这个字段。如果没有,得在Angular的HTTP拦截器里配置自动添加,示例代码如下:
// Angular HTTP拦截器示例,自动给后端请求加Token import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; import { KeycloakService } from 'keycloak-angular'; @Injectable() export class AuthInterceptor implements HttpInterceptor { constructor(private keycloakService: KeycloakService) {} intercept(req: HttpRequest<any>, next: HttpHandler) { // 只给后端API的请求添加Token,避免给其他无关请求加 if (req.url.includes('你的后端API域名/路径')) { const authReq = req.clone({ setHeaders: { Authorization: `Bearer ${this.keycloakService.getToken()}` } }); return next.handle(authReq); } return next.handle(req); } }
别忘了在app.module.ts里把这个拦截器注册进去哦。
二、给Spring Boot后端配置正确的CORS支持
因为前端和后端是不同的域名/端口,浏览器会触发跨域预检请求,后端必须明确允许前端的域名,并且允许携带Authorization头。
你可以在Spring Boot里加个CORS配置类:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); // 替换成你的前端地址,比如http://localhost:4200 config.addAllowedOrigin("http://你的前端域名:端口"); // 允许所有请求头,特别是Authorization config.addAllowedHeader("*"); // 允许所有HTTP方法(GET/POST/PUT等) config.addAllowedMethod("*"); // 允许携带凭证(如果你的场景需要的话,public客户端一般可以开着) config.setAllowCredentials(true); // 对所有后端接口生效 source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }
另外,如果你用了Keycloak的Spring Boot Starter,还要在application.properties里加上:
keycloak.cors=true
这个配置会让Keycloak的过滤器也参与处理CORS请求,避免冲突。
三、检查Keycloak控制台的客户端配置
后端客户端(backendService)
- 确认Access Type是
Bearer-only(你已经设置了,这点没问题) Valid Redirect URIs可以留空或者填*,因为bearer-only客户端不需要跳转- 确保
Authorization Enabled是开启状态
前端客户端
- 确认Access Type是
Public Valid Redirect URIs要填前端的完整路径,比如http://localhost:4200/*- 重点!
Web Origins必须填前端的域名(比如http://localhost:4200),不然Keycloak会限制前端获取的Token用于跨域请求,这是很多人踩坑的点!
四、验证Token是否有效
如果前面的配置都弄好了还是报错,可能是Token本身无效。你可以用Keycloak的自省接口验证一下:
# 替换成你的实际参数 curl -X POST \ http://你的Keycloak地址/auth/realms/testRealm/protocol/openid-connect/token/introspect \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'client_id=backendService&client_secret=你的后端客户端密钥&token=前端拿到的AccessToken'
如果返回结果里的active字段是false,说明Token过期、签名不对或者客户端权限不足,得重新排查前端获取Token的流程。
五、看浏览器控制台的完整错误信息
你提到的错误是Failed to load http://loc...,最好把完整的错误信息贴出来——如果是No 'Access-Control-Allow-Origin' header is present,那就是CORS没配好;如果是401 Unauthorized,那就是Token验证失败,针对性解决就行。
内容的提问来源于stack exchange,提问作者Mahesh_Loya

