首页 > 解决方案 > Keycloak NodeJS 适配器忽略 X-Forwarded-Proto

问题描述

keycloak-connect是 Keycloak 文档中推荐的 NodeJS 适配器,当受保护的应用程序位于 Apache 反向代理之后时,它不会考虑X-Forwarded-Proto标头。

实际上,redirectUri 是这样构建的:

let host = request.hostname;
let headerHost = request.headers.host.split(':');
let port = headerHost[1] || '';
let protocol = request.protocol;*
let hasQuery = ~(request.originalUrl || request.url).indexOf('?');

let redirectUrl = protocol + '://' + host + (port === '' ? '' : ':' + port) + (request.originalUrl || request.url) + (hasQuery ? '&' : '?') + 'auth_callback=1';

request.protocol由于反向代理,始终为“http”,因此 redirectUri 没有预期的协议 (HTTPS)。

如果这是故意的而不是错误,那么即使客户端重定向到 HTTPS,在 redirectUri 中使用 HTTP 是否也是一个安全漏洞?令牌不能同时暴露吗?

标签: node.jssingle-sign-onkeycloak

解决方案


事实证明这是受保护应用程序端的配置问题,这也涉及其他 Keycloak 适配器,例如Java Servlet 过滤器适配器或Spring 适配器

默认情况下,任何受保护的应用程序都将忽略X-Forwarded-Proto标头。

节点JS

使用的 Web 框架(例如 Express)需要配置为考虑代理标头。

对于 Express,文档说明应用程序应该信任代理,例如:

app.set('trust proxy', 'loopback');

Java 适配器

对于 Spring,根据文档,在application.properties中几乎不需要进行配置:

server.tomcat.remote-ip-header=x-forwarded-for
server.tomcat.protocol-header=x-forwarded-proto 

对于 Java Servlet 过滤器,有几种解决方案:

可以将 Tomcat 阀门添加到server.xml

<Valve className="org.apache.catalina.valves.RemoteIpValve" 
           internalProxies="127.0.0.1" 
           remoteIpHeader="x-forwarded-for" 
           proxiesHeader="x-forwarded-by" 
           protocolHeader="x-forwarded-proto" /> 

也可以在Keycloak 的过滤器适配器之前实现一个新的 Servlet 过滤器,注册在web.xml中,就像在这个例子中一样。


推荐阅读