使用接收到的访问令牌检索 Keycloak 用户数据
Retrieve Keycloak user data using received access token
我正在开发一个 WildFly-Backend(在 Java 中),它接受 HTTP 请求(来自自定义前端),这些请求通过 "Authorization" HTTP 使用用户的 Keycloak 承载访问令牌进行签名header.
后端连接本身已经通过 WildFly 的 Keycloak 适配器得到保护,但在内部,我想检查用户是谁(用户组、名称等)和 return 非常反应。
我认为可以只从前端发送此数据,但是一旦人们拥有访问令牌,他们就可以轻松伪造请求。有没有办法在只有访问令牌的情况下检索用户数据之类的东西?
我已经找到解决问题的办法了!
首先,在 class 顶部附近添加以下内容:
@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服务器匹配的版本。
接下来,在您要检索用户信息的位置,检索 UserPrincipal:
if (securityContext != null && securityContext.getUserPrincipal() instanceof KeycloakPrincipal) {
KeycloakPrincipal principal = ((KeycloakPrincipal) securityContext.getUserPrincipal());
附加检查是故障保存,因此可以单独处理非 Keycloak 配置。
从铸造的 KeycloakPrinciple 中,检索 KeycloakSecurityContext 并从那里获取用户的令牌:
AccessToken token = principal.getKeycloakSecurityContext().getToken();
在某些情况下(取决于您的 Keycloak and/or WildFly 的版本),getToken() 可能 return 为空。在这些情况下,使用 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.");
}
我正在开发一个 WildFly-Backend(在 Java 中),它接受 HTTP 请求(来自自定义前端),这些请求通过 "Authorization" HTTP 使用用户的 Keycloak 承载访问令牌进行签名header.
后端连接本身已经通过 WildFly 的 Keycloak 适配器得到保护,但在内部,我想检查用户是谁(用户组、名称等)和 return 非常反应。
我认为可以只从前端发送此数据,但是一旦人们拥有访问令牌,他们就可以轻松伪造请求。有没有办法在只有访问令牌的情况下检索用户数据之类的东西?
我已经找到解决问题的办法了!
首先,在 class 顶部附近添加以下内容:
@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服务器匹配的版本。
接下来,在您要检索用户信息的位置,检索 UserPrincipal:
if (securityContext != null && securityContext.getUserPrincipal() instanceof KeycloakPrincipal) {
KeycloakPrincipal principal = ((KeycloakPrincipal) securityContext.getUserPrincipal());
附加检查是故障保存,因此可以单独处理非 Keycloak 配置。
从铸造的 KeycloakPrinciple 中,检索 KeycloakSecurityContext 并从那里获取用户的令牌:
AccessToken token = principal.getKeycloakSecurityContext().getToken();
在某些情况下(取决于您的 Keycloak and/or WildFly 的版本),getToken() 可能 return 为空。在这些情况下,使用 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.");
}