使用收到的访问令牌检索 Keycloak 用户数据



我正在开发一个WildFly-Back(Java(,它接受HTTP请求(来自自定义前端(,这些请求通过"授权"HTTP标头使用用户的Keycloak持有者访问令牌进行签名。

后端连接本身已经使用 WildFly 的 Keycloak 适配器进行保护,但在内部,我想检查用户是谁(用户组、名称等(并返回非常正确的响应。

我认为可以从前端发送这些数据,但是一旦人们拥有访问令牌,就可以轻松地伪造请求。有没有办法在只有访问令牌的情况下检索用户数据等内容?

我已经想出了解决问题的方法!

首先,在类的顶部附近添加以下内容:

@Context
javax.ws.rs.core.SecurityContext securityContext;

这将注入服务器安全性的上下文。要使用Keycloak,WildFly需要安装Wildfly适配器,并且必须将web.xml配置为使用Keycloak。

在我们继续之前,我们需要 Keycloak-Core 库,例如每个 Maven:

<!-- https://mvnrepository.com/artifact/org.keycloak/keycloak-core -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-core</artifactId>
<version>4.4.0.Final</version>
</dependency>

4.4.0.Final是撰写此答案时的最新版本;建议使用最新版本或与Keycloak服务器匹配的版本。

接下来,在要检索用户信息的位置,检索用户主体:

if (securityContext != null && securityContext.getUserPrincipal() instanceof KeycloakPrincipal) {
KeycloakPrincipal principal = ((KeycloakPrincipal) securityContext.getUserPrincipal());

附加检查是失败的,因此可以单独处理非 Keycloak 配置。

从强制转换的KeycloakPrinciple中,检索KeycloakSecurityContext,并从那里检索用户的令牌:

AccessToken token = principal.getKeycloakSecurityContext().getToken();

在某些情况下(取决于Keycloak和/或WildFly的版本(,getToken((可能会返回null。在这些情况下,请使用getIdToken((:

IDToken token = principal.getKeycloakSecurityContext().getIdToken();

AccessToken 扩展了 IDToken,因此您在这两种情况下都拥有完整的功能(针对此上下文(。

从令牌中,可以提取所有用户数据。例如,我们获取用户的用户名。在Keycloak中,这个属性被称为"首选用户名"。

String user = token.getPreferredUsername();

大功告成!您的完整代码现在可能如下所示:

if (securityContext != null && securityContext.getUserPrincipal() instanceof KeycloakPrincipal) {
KeycloakPrincipal principal = ((KeycloakPrincipal) securityContext.getUserPrincipal());
AccessToken token = principal.getKeycloakSecurityContext().getToken();
// IDToken token = principal.getKeycloakSecurityContext().getIdToken();
System.out.println("User logged in: " + token.getPreferredUsername());
} else {
System.out.println("SecurityContext could not provide a Keycloak context.");
}

最新更新