Keycloak OIDC Filter的redirect_uri始终为http的问题求助
Keycloak 10.0.2 Servlet Filter 适配HTTPS redirect_uri 问题解决
针对你遇到的redirect_uri始终为HTTP的问题,提供以下几种解决方案:
1. 让适配器自动识别请求协议(适配反向代理场景)
Keycloak Servlet适配器默认从HttpServletRequest获取协议,但如果应用部署在反向代理(如Nginx、Apache)后,request.isSecure()会返回false,导致生成HTTP的redirect_uri。开启代理地址转发配置即可解决:
配置方式二选一:
- 通过keycloak.json配置:
{ // 其他原有配置 "proxy-address-forwarding": true, "trust-all-certificates": true // 可选,若代理使用自签证书 }
- 通过web.xml的过滤器初始化参数配置:
<filter> <filter-name>keycloak</filter-name> <filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class> <init-param> <param-name>keycloak.config.skipPattern</param-name> <param-value>/((error-page.html)|(access-denied-page.html))</param-value> </init-param> <init-param> <param-name>keycloak.proxy-address-forwarding</param-name> <param-value>true</param-value> </init-param> </filter>
开启后,适配器会读取代理传递的X-Forwarded-Proto等头信息,自动匹配请求的HTTP/HTTPS协议生成redirect_uri。
2. 强制所有redirect_uri使用HTTPS
如果不需要区分HTTP/HTTPS场景,直接固定redirect_uri为HTTPS:
配置方式二选一:
- keycloak.json配置:
{ // 其他原有配置 "redirect-uri": "https://test.subok.com/*" }
- web.xml配置:
<filter> <filter-name>keycloak</filter-name> <filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class> <init-param> <param-name>keycloak.config.skipPattern</param-name> <param-value>/((error-page.html)|(access-denied-page.html))</param-value> </init-param> <init-param> <param-name>keycloak.redirect-uri</param-name> <param-value>https://test.subok.com/*</param-value> </init-param> </filter>
*作为通配符,适配不同路径的回调请求。
3. 自定义过滤器扩展(灵活控制协议)
如果以上方案不满足需求,可以自定义KeycloakOIDCFilter子类,重写redirect_uri的生成逻辑:
自定义过滤器类:
package com.yourcompany.yourpackage; import org.keycloak.adapters.servlet.KeycloakOIDCFilter; import org.keycloak.adapters.spi.OIDCSessionStore; import javax.servlet.http.HttpServletRequest; public class CustomKeycloakOIDCFilter extends KeycloakOIDCFilter { @Override protected String resolveRedirectUri(OIDCSessionStore<HttpServletRequest> sessionStore, HttpServletRequest request) { String originalUri = super.resolveRedirectUri(sessionStore, request); // 根据代理头判断协议,替换为HTTPS String forwardedProto = request.getHeader("X-Forwarded-Proto"); if (forwardedProto != null && forwardedProto.equalsIgnoreCase("https")) { return originalUri.replaceFirst("http://", "https://"); } // 若不需要自动识别,直接强制替换为HTTPS // return originalUri.replaceFirst("http://", "https://"); return originalUri; } }
修改web.xml引用自定义过滤器:
<filter> <filter-name>keycloak</filter-name> <filter-class>com.yourcompany.yourpackage.CustomKeycloakOIDCFilter</filter-class> <init-param> <param-name>keycloak.config.skipPattern</param-name> <param-value>/((error-page.html)|(access-denied-page.html))</param-value> </init-param> </filter>
Wicket框架适配注意事项
Wicket会对HttpServletRequest进行包装,需确保代理传递的头信息能被Keycloak过滤器获取。可在Wicket的WebApplication初始化方法中添加配置:
@Override protected void init() { super.init(); // 确保请求头正确传递 getServletContext().setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true); }
内容的提问来源于stack exchange,提问作者Borgy Manotoy
相关产品推荐
相关产品推荐

