Tomcat 9远程Web应用Keycloak认证失败问题求助
问题描述
我有两种部署环境:
- 第一种环境:Keycloak实例部署在一台虚拟机(VM)上,Tomcat实例部署在本地笔记本电脑。通过
http://127.0.0.1:8080/my_app访问Web应用,流程正常:浏览器重定向到Keycloak登录页,认证完成后Keycloak重定向回应用。 - 第二种环境:使用同一Keycloak实例(第一台VM),Tomcat部署在另一台独立虚拟机(第二台VM),通过
http://tomcat.ip:8080/my_app访问应用。此时浏览器能重定向到Keycloak登录页,登录成功后Keycloak控制台可见会话,但重定向回应用时出现错误,地址栏显示http://tomcat.ip:8080/my_app/login?error,错误信息:
Login with OAuth 2.0
Invalid credentials
catalina.out和Keycloak日志均无额外报错。使用版本:Tomcat 9.0.83、Keycloak 24.0.1,两台Tomcat配置完全一致,第二台Tomcat目录直接复制自第一台。
解决思路
1. 检查Keycloak客户端的重定向URI配置
Keycloak对客户端的重定向URI有严格校验,务必确保第二台Tomcat的应用地址已添加到对应客户端的Valid Redirect URIs列表中。比如要添加http://tomcat.ip:8080/my_app/*(注意通配符的正确使用),不能只保留本地的http://127.0.0.1:8080/my_app/*。
2. 验证Tomcat的外部访问识别配置
当Tomcat部署在虚拟机且通过外部IP访问时,需要让Tomcat正确识别外部请求的真实地址,否则Keycloak返回的回调地址会和Tomcat内部识别的地址不匹配,导致会话验证失败。可以在Tomcat的server.xml中配置RemoteIpValve:
<Valve className="org.apache.catalina.valves.RemoteIpValve" remoteIpHeader="X-Forwarded-For" protocolHeader="X-Forwarded-Proto" protocolHeaderHttpsValue="https"/>
同时检查Tomcat启动参数,确认server.name或address设置正确,保证应用对外暴露的地址和Keycloak配置一致。
3. 确认Tomcat的Cookie与会话配置
- 检查两台Tomcat的
context.xml中CookieProcessor的配置,确保sameSite属性设置合理(比如跨域场景设为Lax或None),避免Cookie无法正常传递到应用。 - 确认第二台Tomcat的会话ID生成机制和本地一致,若配置了分布式会话,需检查会话共享是否正常。
4. 排查网络层面的请求篡改
确认从笔记本到第二台Tomcat的请求没有被防火墙、代理服务器篡改请求头(比如Host头),导致Tomcat收到的请求地址和浏览器访问的地址不一致。可以通过浏览器开发者工具查看重定向回应用时的请求头,对比Host、Referer等字段是否正确。
5. 开启调试日志获取细节
虽然当前日志无报错,但调高日志级别能拿到更多认证过程的细节:
- Keycloak:在
standalone.xml或domain.xml中把org.keycloak的日志级别改为DEBUG,查看认证回调时的参数传递情况。 - Tomcat:修改
logging.properties,将org.apache.catalina.authenticator和org.keycloak.adapters的日志级别设为FINE或DEBUG,追踪回调时的认证处理流程。
内容的提问来源于stack exchange,提问作者Ubuntu Learner

