服务器端使用 Bearer 令牌以编程方式在 Java 中验证 Keycloak 用户
Posted
技术标签:
【中文标题】服务器端使用 Bearer 令牌以编程方式在 Java 中验证 Keycloak 用户【英文标题】:Serverside Authenticate Keycloak user programmatically in Java with Bearer token 【发布时间】:2018-10-03 09:02:49 【问题描述】:我想使用 Keycloak 和 Bearer 令牌在我的 Java REST 端点中对用户进行身份验证。
我想要实现的工作流程如下:
-
客户端使用用户名和密码登录 Keycloak。
Keycloak 返回一个 Bearer 令牌(一个 JWT 令牌,如果我没记错的话,我该如何检查?)。
客户端执行带有
'Authorization' : 'Bearer <token>'
标头的Http请求。
REST 端点(用 Java 编写)检查接收到的令牌是否正确,并验证从 Keycloak 接收委托人的用户(如果我理解正确的话)。
通过身份验证后,端点将检查用户是否有权访问该 REST api 并发回响应。
1、2、3 和 5 已经实现并且正在运行,但我找不到实现 4 的方法。
我已经尝试了不同的方法:
我的 Java 端点在 WildFly 10.x 上发布的 EAR 中运行,因此我在 web.xml
中使用了 security-constraint
,并通过 keycloak.json
配置了 Keycloak。
这很好用,但我需要在相同的 Web 上下文中保留一些 REST 端点(即使没有“授权”标头也可以访问),据我所知,没有办法只过滤我的安全约束中的一些请求。
我尝试实现 BearerTokenRequestAuthenticator
,但绝对没有成功,即使我可以,我也不认为我会收到一个 Principal 作为我的身份验证请求的结果。
现在我已经实现了一种过滤请求的方法,并且需要身份验证的请求被我实现的ServiceSecurityInterceptor
类拦截。
在该类的某个时刻,我检查“授权”标头是否包含 Basic
或 Bearer
:
User loggedUser = null;
if (authorizationType.equals("Basic"))
// ... decode Base64 username and password ...
loggedUser = userManagerBean.login(username, password);
else if (authorizationType.equals("Bearer"))
String token = ...; // Get token from header
// ... Here is where I need to send the token to Keycloak and receive a Principal with the username ...
loggedUser = userManagerBean.login(username):
我在某些地方读到我可能需要来自我的 Keycloak 领域的公钥,但是一旦我有了它,我应该怎么做?
【问题讨论】:
【参考方案1】:几个月前,我们推出了 Keycloak。诀窍是让 Keycloak 为您完成工作。我猜你正在使用 OpenId 连接?看看这些Java-Adapters。也许this one 可以为您处理 url 模式匹配。
就我自己而言,我更喜欢将 Spring Boot 安全性与 keycloak 结合使用。 Keycloak Spring Boot Adapter 与 Java 应用程序集成得很好。您只需在 Java 应用程序和 Keycloak 服务器上进行一些配置。身份验证过程由 KeyCloak 和 Keycloak Adapter 自动处理。使用 Spring boot,您还可以为 WildFly 服务器创建一个 ear 包。 KeyCloakPrincipial 是在 Springs 安全上下文中自动创建的 (SecurityContextHolder.getContext().getAuthentication().getPrincipal())
【讨论】:
以上是关于服务器端使用 Bearer 令牌以编程方式在 Java 中验证 Keycloak 用户的主要内容,如果未能解决你的问题,请参考以下文章