如何在纯Tomcat环境下验证Keycloak颁发的access_token
纯Tomcat无Spring依赖场景下的Keycloak access_token校验方案
以下是生产环境验证过的可行方案,全程不需要引入任何Spring相关依赖,适配传统WAR包部署到独立Tomcat的架构:
方案1:本地JWT签名校验(性能最优,优先选)
Keycloak默认签发的access_token是标准JWT格式,完全可以在应用本地完成校验,不需要每次请求都和Keycloak服务端交互。
实现逻辑:- 项目启动时拉取对应realm的公开公钥,缓存在本地内存即可,这个公钥公开可访问,不需要额外鉴权;如果开启了密钥轮换,加个定时任务每小时拉取一次最新公钥更新缓存即可
- 自定义实现
javax.servlet.Filter接口,在web.xml里配置拦截需要鉴权的路径,过滤器逻辑中先从请求头Authorization字段提取Bearer前缀后的token串 - 引入轻量JWT库(比如jjwt核心包,总依赖体积不到1M)做规则校验:先验证JWT签名和本地缓存的公钥是否匹配,再依次校验
exp过期时间、iss签发者地址是否为对接的Keycloak实例地址、aud受众是否包含当前应用的客户端ID,所有校验通过即放行请求,否则直接返回401状态码 - 校验通过后把解析出的用户ID、角色等信息存入request的Attribute中,后续业务代码可直接从请求上下文取值
该方案无额外网络开销,性能最好,依赖极少,是绝大多数场景的首选。
方案2:调用Token自省接口远程校验(适合reference token场景)
如果在Keycloak配置中把access_token设置为随机字符串格式(reference token,非JWT结构),或者安全等级要求极高不接受本地校验逻辑,可以选择该方案。
实现逻辑:- 同样通过自定义Servlet Filter拦截请求,提取token后,使用提前配置好的客户端凭证(client_id和client_secret)做Basic鉴权,调用Keycloak的令牌自省接口
- 解析接口返回的JSON结果,如果
active字段为true即说明token合法,返回结果中会附带用户信息、权限范围、过期时间等内容,可直接绑定到请求上下文使用;如果active字段为false直接返回401状态码 - 依赖仅需要HTTP客户端组件(用JDK自带的
HttpURLConnection即可,也可引入轻量的Apache HttpClient)加JSON解析包(Gson、Jackson core均可),完全不涉及Spring相关依赖
注意该方案每次请求都需要和Keycloak做网络交互,性能弱于本地校验,高并发场景下可以给校验结果加30s到1min的本地缓存,降低Keycloak服务端压力。
方案3:使用Keycloak官方Tomcat适配器(零开发量)
Keycloak官方原生提供了不依赖Spring的Tomcat适配包,专门面向传统Servlet架构应用,不需要自行编写校验逻辑。
实现逻辑:- 引入与当前Keycloak服务端版本完全一致的
keycloak-tomcat-adapter依赖,该包本身仅依赖Servlet API和Keycloak核心鉴权库,无Spring相关传递依赖 - 在WEB-INF目录下添加
keycloak.json配置文件,填写realm名称、Keycloak服务地址、当前应用的客户端ID/密钥、路径拦截规则、角色权限映射等配置 - 在web.xml中配置
KeycloakAuthenticatorValve和对应安全约束,适配器会自动完成token校验、权限判断、未登录拦截全流程,业务代码直接从request中读取用户信息即可
注意适配器版本必须和Keycloak服务端版本严格对齐,避免出现协议兼容问题。
- 引入与当前Keycloak服务端版本完全一致的
三个方案都完全符合纯Tomcat、无Spring Boot依赖的要求,不需要改动Tomcat核心配置,仅需要遵循Servlet标准添加过滤器或者Valve即可落地。
内容的提问来源于stack exchange,提问作者Limon
相关产品推荐
相关产品推荐

