Keycloak 10集成非Boot Spring应用报CODE_TO_TOKEN_ERROR错误如何解决
我正在使用Keycloak 10版本为现有未引入Spring Boot库的Spring应用做身份认证,参考Keycloak官方文档提供的Java适配器,在Spring Security配置中添加了官方建议的配置项。
以下是我的keycloak.json配置文件内容:
{ "realm": "cnp-server", "auth-server-url": "http://localhost:8081/auth/", "ssl-required": "external", "resource": "cnpserver-client", "public-client": true, "confidential-port": 0 }
运行在Docker中的Keycloak客户端配置如下图所示:
当我尝试访问应用时,浏览器会正常重定向到如下地址:
http://localhost:8081/auth/realms/cnp-server/protocol/openid-connect/auth?response_type=code&client_id=cnpserver-client&redirect_uri=http%3A%2F%2Flocalhost%3A8088%2Fcnp_server_web_war%2Fsso%2Flogin&state=73ee7ebe-1949-4e94-9349-f3760f37bb4a&login=true&scope=openid
但我在弹出的认证框中输入访问凭证后出现异常,Keycloak日志输出如下警告:
WARN [org.keycloak.events] (default task-63) type=CODE_TO_TOKEN_ERROR, realmId=cnp-server, clientId=cnpserver-client, userId=null, ipAddress=192.168.32.1, error=invalid_code, grant_type=authorization_code, code_id=7972a766-f9be-4907-85a7-69e6d5d50cbf, client_auth_method=client-secret
Spring应用日志输出如下错误:
ERROR org.keycloak.adapters.OAuthRequestAuthenticator [OAuthRequestAuthenticator.java:337] - failed to turn code into token
ERROR org.keycloak.adapters.OAuthRequestAuthenticator [OAuthRequestAuthenticator.java:338] - status from server: 400
ERROR org.keycloak.adapters.OAuthRequestAuthenticator [OAuthRequestAuthenticator.java:340] - {"error":"invalid_grant","error_description":"Code not valid"}
我没有对redirect-uri做任何自定义配置,也不清楚如何修改该配置,请问该如何排查解决这个问题?
你遇到的invalid_code+Code not valid报错是授权码流程的常见问题,结合Docker部署、未自定义redirect_uri的场景,按优先级从高到低排查即可:
- 优先校验客户端访问类型与配置不匹配的问题:
你的keycloak.json里配置了"public-client": true,说明你将客户端定义为公共类型,但Keycloak日志明确标注client_auth_method=client-secret,说明Keycloak端将该客户端识别为需要校验密钥的保密类型,二者不匹配会直接导致换token失败。
解决方法:打开Keycloak客户端配置页,将「Access Type」选项从confidential改为public,保存后清空浏览器缓存、重启应用重试即可。 - 第二校验Docker部署的地址一致性问题:
你本地浏览器访问Keycloak用的是http://localhost:8081/auth,但Spring应用和Keycloak容器内部交换授权码时,用的地址可能和浏览器端地址不一致,导致授权码绑定的访问上下文和后端请求上下文不匹配。
解决方法:修改keycloak.json中的auth-server-url,如果Spring应用在宿主机运行,就填Keycloak容器的内网IP地址;如果Spring应用也在同Docker网络下运行,直接填Keycloak的服务名作为域名,保证后端请求Keycloak的地址和浏览器跳转的地址完全一致。 - 第三校验重定向URI白名单配置:
你当前跳转的redirect_uri是http://localhost:8088/cnp_server_web_war/sso/login,需要在Keycloak客户端配置的「Valid Redirect URIs」中添加该地址,也可以先填*做临时测试,确认是白名单问题后再收紧权限。 - 第四校验授权码超时/重复使用问题:
Keycloak默认授权码有效期仅为1分钟,如果应用和Keycloak服务器的时间差超过1分钟,或是你重复刷新回调页面导致授权码被重复使用,也会触发该报错。可以同步两边服务器时间,不要重复刷新回调页面重试即可。
内容的提问来源于stack exchange,提问作者giuseppe trubia

