1. Overview
1.概述
Keycloak is an open-source identity and access management (IAM) system that integrates well with the Spring Boot application. In this tutorial, we’ll describe how to get Keycloak user ID in a Spring Boot application.
Keycloak是一个开源的身份和访问管理(IAM)系统,可以很好地与Spring Boot应用程序集成。在本教程中,我们将介绍如何在Spring Boot应用程序中获得Keycloak用户ID。
2. Problem Statement
2 问题陈述
Keycloak provides features such as securing a REST API, user federation, fine-grained authorization, social login, two-factor authentication (2FA), etc. Moreover, we can use it for implementing single sign-on (SSO) using OpenID Connect (OIDC). Let’s assume that we have a Spring Boot application secured by OIDC using Keycloak, and we want to get a user ID in the Spring Boot application. In this situation, we’ll need to get an access token or security context in the Spring Boot application.
Keycloak提供的功能包括保护REST API的安全、用户联盟、细粒度授权、社交登录、双因素认证(2FA)等。此外,我们可以使用它来实现单点登录(SSO),使用OpenID Connect(OIDC)。让我们假设我们有一个由OIDC使用Keycloak担保的Spring Boot应用程序,并且我们想在Spring Boot应用程序中获得一个用户ID。在这种情况下,我们需要在Spring Boot应用程序中获得一个访问令牌或安全上下文。
2.1. Keycloak Server as Authorization Server
2.1.Keycloak服务器作为授权服务器
To keep things simple, we’ll be using Keycloak embedded in a Spring Boot application. Let’s assume that we’re using the authorization server project available on GitHub. First, we’ll define the customerClient client in realm baeldung in our embedded Keycloak server: Then, we export the realm details as customer-realm.json and set the realm file in our application-customer.yml:
为了保持简单,我们将使用嵌入Spring Boot应用程序中的Keycloak。让我们假设我们正在使用GitHub上提供的授权服务器项目。首先,我们将在嵌入式Keycloak服务器中的境界baeldung中定义customerClient客户端。 然后,我们将境界细节导出为customer-realm.json并在我们的application-customer.yml中设置该境界文件。
keycloak:
server:
contextPath: /auth
adminUser:
username: bael-admin
password: pass
realmImportFile: customer-realm.json
Finally, we can run the application using the –spring.profiles.active=customer option. Now, the authorization server is ready. After running the server, we can access the authorization server’s welcome page at http://localhost:8083/auth/.
最后,我们可以使用-spring.profiles.active=customer选项来运行该应用程序。现在,授权服务器已经准备好了。运行服务器后,我们可以在http://localhost:8083/auth/.访问授权服务器的欢迎页面。
2.2. Resource Server
2.2.资源服务器
Now that we’ve configured the authorization server, let’s set up the resource server. For that, we’ll use the resource server project available on GitHub. First, let’s add the application-embedded.properties file as a resource:
现在我们已经配置了授权服务器,让我们来设置资源服务器。为此,我们将使用资源服务器项目在GitHub上提供。首先,让我们把application-embedded.properties文件添加为资源。
keycloak.auth-server-url=http://localhost:8083/auth
keycloak.realm=baeldung
keycloak.resource=customerClient
keycloak.public-client=true
keycloak.principal-attribute=preferred_username
Now, the resource server is secure using the OAuth2 authorization server, and we must log in to the SSO server to access the resources. We can run the application using the –spring.profiles.active=embedded option.
现在,资源服务器使用OAuth2授权服务器是安全的,我们必须登录到SSO服务器才能访问资源。我们可以使用-spring.profiles.active=embedded选项来运行该应用程序。
3. Get Keycloak User ID
3.获取Keycloak用户ID
Getting the user ID from Keycloak can be accomplished in a few ways: using an access token or client mapper.
从Keycloak获取用户ID可以通过几种方式完成:使用访问令牌或客户端映射器。
3.1. By Access Token
3.1.通过访问令牌
Building on top of the Spring Boot application CustomUserAttrController class, let’s modify the getUserInfo() method to get the user ID:
在Spring Boot应用程序 CustomUserAttrController类的基础上,我们来修改getUserInfo()方法以获取用户ID。
@GetMapping(path = "/users")
public String getUserInfo(Model model) {
KeycloakAuthenticationToken authentication =
(KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
Principal principal = (Principal) authentication.getPrincipal();
String userIdByToken = "";
if (principal instanceof KeycloakPrincipal) {
KeycloakPrincipal<KeycloakSecurityContext> kPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) principal;
IDToken token = kPrincipal.getKeycloakSecurityContext().getIdToken();
userIdByToken = token.getSubject();
}
model.addAttribute("userIDByToken", userIdByToken);
return "userInfo";
}
As we can see, first we obtained the Principal from the KeycloakAuthenticationToken class. Then, we extract the user ID from IDToken using the getSubject() method.
我们可以看到,首先我们从KeycloakAuthenticationToken类中获得Principal。然后,我们使用 getSubject()方法从IDToken提取用户ID。
3.2. By Client Mapper
3.2.通过客户端映射器
We can add a user ID in the client mapper and get it in the Spring Boot application. First, we define a client mapper in the customerClient client: Then, we get the user ID in the CustomUserAttrController class:
我们可以在客户端映射器中添加一个用户ID,并在Spring Boot应用程序中获得它。首先,我们在customerClientclient中定义一个客户端映射器。 然后,我们在CustomUserAttrController类中获得用户ID。
@GetMapping(path = "/users")
public String getUserInfo(Model model) {
KeycloakAuthenticationToken authentication =
(KeycloakAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
Principal principal = (Principal) authentication.getPrincipal();
String userIdByMapper = "";
if (principal instanceof KeycloakPrincipal) {
KeycloakPrincipal<KeycloakSecurityContext> kPrincipal = (KeycloakPrincipal<KeycloakSecurityContext>) principal;
IDToken token = kPrincipal.getKeycloakSecurityContext().getIdToken();
userIdByMapper = token.getOtherClaims().get("user_id").toString();
}
model.addAttribute("userIDByMapper", userIdByMapper);
return "userInfo";
}
We use the getOtherClaims() method from IDToken for getting the mapper. Then, we add the user ID to the model attribute.
我们使用来自IDToken的getOtherClaims()方法来获取映射器。然后,我们将用户ID添加到模型属性中。
3.3. Thymeleaf
3.3.百里香叶
We’ll modify the userInfo.html template to display the user ID information:
我们将修改userInfo.html模板以显示用户ID信息。
<div id="container">
<h1>
User ID By Token: <span th:text="${userIDByToken}">--userID--</span>.
</h1>
<h1>
User ID By Mapper: <span th:text="${userIDByMapper}">--userID--</span>.
</h1>
</div>
3.4. Test
3.4. 测试
After running the application, we can navigate to http://localhost:8081/users. Entering baeldung:baeldung for the credentials, will return the following:
运行应用程序后,我们可以导航到http://localhost:8081/users。输入baeldung:baeldung作为凭证,将返回以下信息。
4. Conclusion
4.总结
In this article, we looked at getting the user ID from Keycloak in a Spring Boot application. We first set up the required environment for invoking a secure application. Then, we described getting Keycloak user ID in the Spring Boot application using IDToken and client mapper. As always, the full source code of this tutorial is available over on GitHub. Additionally, the authorization server source code is available over on GitHub.
在这篇文章中,我们研究了在Spring Boot应用程序中从Keycloak获取用户ID。我们首先设置了调用安全应用程序的必要环境。然后,我们描述了在Spring Boot应用程序中使用IDToken和客户端映射器获得Keycloak用户ID。一如既往,本教程的完整源代码可在GitHub上获得。此外,授权服务器的源代码在GitHub上提供。