如何修改Keycloak的FTL文件嵌入Java代码展示外部API信息
Keycloak FTL实现登录后外部接口信息展示方案
核心前提:Keycloak默认对FreeMarker(FTL)模板开启了类访问沙箱,无法直接编写任意Java代码,需要先配置白名单放开指定类的访问权限,再按流程实现逻辑
1. 配置FTL模板Java类访问白名单
- 找到Keycloak配置文件:单机部署对应路径为
standalone/configuration/standalone.xml,容器部署则挂载对应配置文件到容器内,定位到keycloak-server的spi配置段,添加freemarker引擎的允许访问类配置:
<spi name="freemarker"> <provider name="default" enabled="true"> <properties> <property name="allowedClasses" value="java.net.http.HttpClient,java.net.http.HttpRequest,java.net.http.HttpResponse,java.net.URI,com.fasterxml.jackson.databind.ObjectMapper"/> </properties> </provider> </spi>
- 保存配置后重启Keycloak节点,配置即可生效。
2. 创建自定义中转页FTL模板
- 进入Keycloak主题目录,在你使用的登录主题的login文件夹下,新建
post-login-notice.ftl模板文件,不要直接修改原有登录页模板避免破坏默认流程。 - 在模板中编写逻辑调用Java类拉取外部接口数据、渲染页面、配置自动跳转,参考实现如下:
<#-- 初始化Java类,发起外部REST API请求 --> <#assign HttpClient = statics["java.net.http.HttpClient"]> <#assign HttpRequest = statics["java.net.http.HttpRequest"]> <#assign HttpResponse = statics["java.net.http.HttpResponse"]> <#assign URI = statics["java.net.URI"]> <#assign ObjectMapper = statics["com.fasterxml.jackson.databind.ObjectMapper"]> <#assign httpClient = HttpClient.newBuilder() .connectTimeout(java.time.Duration.ofSeconds(3)) .build()> <#assign objectMapper = ObjectMapper()?> <#-- 构造接口请求,可根据需求修改请求方法、添加请求头、传入当前登录用户信息 --> <#assign apiReq = HttpRequest.newBuilder() .uri(URI.create("替换为你的外部REST API地址")) .header("Accept", "application/json") .GET() .build()> <#assign apiResp = httpClient.send(apiReq, HttpResponse.BodyHandlers.ofString())> <#assign apiData = objectMapper.readValue(apiResp.body(), java.util.Map.class)> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>登录成功</title> <#-- 配置停留X秒后自动跳转,示例为5秒,可自行修改时长 --> <meta http-equiv="refresh" content="5;url=${redirectUri}"> <style> .notice-wrap {max-width: 600px;margin: 100px auto;padding: 2rem;text-align: center;} </style> </head> <body> <div class="notice-wrap"> <h2>登录验证成功</h2> <#-- 按外部接口返回的字段结构渲染内容,以下为示例 --> <div class="notice-content"> <p>${apiData.notice!""}</p> <p style="margin-top:2rem;color:#666;">页面将在5秒后自动跳转至业务系统,若未自动跳转请<a href="${redirectUri}">点击此处</a></p> </div> </div> </body> </html>
3. 配置登录流接入自定义页面
- 登录Keycloak管理控制台,进入对应使用的Realm,打开「Authentication」-「Flows」页面,复制默认的browser登录流生成自定义登录流。
- 在自定义登录流中,找到凭证验证通过后的节点位置,添加
FreeMarker Template类型的执行节点,节点配置选择刚才创建的post-login-notice.ftl模板,将节点执行要求设置为「Required」。 - 调整节点执行顺序:确保凭证验证通过后先执行自定义模板节点,再执行原有的重定向节点,配置完成后将Realm的browser登录流绑定为你修改后的自定义流即可。
注意事项
- 外部接口请求必须配置超时时间,避免接口故障阻塞整个登录流程
- 若接口需要传递当前登录用户信息,可直接从FTL内置的
user对象获取属性(如user.id、user.username),无需额外开发- 跳转地址直接使用登录上下文内置的
redirectUri变量,不要硬编码业务系统地址,避免多业务接入时跳转异常
内容的提问来源于stack exchange,提问作者Nicholas
相关产品推荐
相关产品推荐

