服务器端使用 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 类拦截。

在该类的某个时刻,我检查“授权”标头是否包含 BasicBearer

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 用户的主要内容,如果未能解决你的问题,请参考以下文章

接口认证方式:Bearer Token

如何生成 Bearer 令牌以调用远程 Web API

使用NodeJS验证包含“Bearer:”的JWT标记字符串

Bearer 用于身份验证令牌,但用于不同的令牌?

如何正确使用 Bearer 代币?

使用 .NET Core 中的公共安全密钥配置 JWT Bearer 令牌验证