- vừa được xem lúc

Keycload + Spring boot: Bắt đầu với Keycload và Spring boot - Bắt đầu làm việc với User trong Realm

0 0 227

Người đăng: Nguyen Dat

Theo Viblo Asia

Note: Chuỗi bài viết chủ yếu mang tính lưu trữ kiến thức cho bản thân và chia sẻ lại cho các bạn. Vì khi mình bắt đầu làm việc với Keycload thì rất khó tìm các hướng dẫn bằng tiếng việt. Bài viết có tham khảo từ nhiều nguồn khác nhau. Thanks !

1. Keycload là gì?

Cơ bản Keycloak là một Open Source Identity và Access Management cho Modern Applications và Services. Dùng để quản lý nhận dạng và truy cập vào các ứng dụng/ dịch vụ.
Về hướng dẫn cài đặt, cách thêm realm, client, role, user trên giao diện web của Keycloak thì các bạn có thể check google hoặc tại đây: Link1 hoặc tại đây: Link2 ( Các bạn ấy viết rất đầy đủ và chi tiết về các thông số hiển thị trên giao diện của Keycload)

2. Vậy đã có hướng dẫn rồi thì mình viết về vấn đề gì?

Nếu một ngày đẹp trời, bạn cho phép một người ( đơn vị) thứ 3 nhảy vào thao tác với ứng dụng Keycload của bạn nhưng lại không muốn cho họ có quyền vào thẳng ứng dụng của bạn để thực hiện.... Chà. Vậy bạn cần 1 ứng dụng/APIs cho họ gọi để thao tác với Keycload. Vậy bạn cần tương tác với Keycload từ code chứ không phải từ giao diện.

3. Nếu đây là vấn đề bạn quan tâm => vậy bắt đầu thôi!

Để bắt đầu, Mình khuyên các bạn nên đọc qua hai bài viết mình đã giới thiệu và tạo được realm, client, role và 1 user cho client.
Chú ý!!!!! Mình đã mất nửa ngày cho vấn đề đơn giản này => Đó là Role Mapping của user

Như ảnh bên dưới, 1 user có 2 kiểu role Realm RolesClient Roles Realm Roles : Các bạn sẽ tạo được khi tạo xong Realm Client Roles: Đây là vấn đề chính. Để user có quyền thao tác và call API của Keycload các bạn phải set client role cho user đó, có rất nhiều loại quyền, các bạn có thể đọc chi tiết.
Ở bài demo này mình sẽ sử dụng quyền realm-management và Available Roles là realm-admin

3.1 Dependency

Để sử dụng Keycload trong Spring boot thì các bạn cần:

  1. Đương nhiên 1 ứng dụng spring cơ bản rồi, Gradle hay Maven đều được
  2. Dependency của Keycload

Với Gradle các bạn thêm vào file build.gradle

	implementation group: 'org.keycloak', name: 'keycloak-spring-boot-starter', version: '16.1.0' implementation group: 'org.keycloak', name: 'keycloak-admin-client', version: '16.1.0'

Với Maven thì các bạn thêm vào file pom

<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-spring-boot-starter</artifactId> <version>16.1.0</version>
</dependency>
<dependency> <groupId>org.keycloak</groupId> <artifactId>keycloak-admin-client</artifactId> <version>16.1.0</version>
</dependency>

3.2 Tạo Keycload Instance


Mình sẽ viết 1 hàm để lấy ra instance của keycload. ***env*** là biến môi trường để lấy ra dữ liệu đã lưu trong file .properties hoặc .yaml ( Dùng Spring thì 100% các bạn thừa biết rồi , cứ vẽ vời thêm chuyện!!!!)
Hàm để lấy ra instance có dạng này Keycloak.getInstance(serverUlr, realm, username, password, clientId, clientSecret)
Các bạn nên viết 1 file utils như này
 @Autowired Environment env; public Keycloak getKeycloakInstance() { return Keycloak.getInstance( env.getProperty("keycloak.auth-server-url"), env.getProperty("keycloak.realm"), env.getProperty("keycloak-config.username"), env.getProperty("keycloak-config.password"), env.getProperty("keycloak.resource"), env.getProperty("keycloak-config.client-secret")); }

Sau đó các bạn cần dùng ở đâu thì gọi ra thôi
 @Autowired KeycloakUtils keycloakUtils; public void getListUser(UserRegisterRequest request) { Keycloak keycloak = keycloakUtils.getKeycloakInstance(); .....

3.2 Lấy token ( nếu cần)

Token phục vụ api login

keycloak.tokenManager().getAccessToken().getToken();
keycloak.tokenManager().getAccessToken().getExpiresIn(); 

3.3 Lấy danh sách users

Lưu ý: các bạn chỉ có thể lấy ra danh sách user của client mà user admin đã dùng để lấy Keycloak instance thôi nhé!!!!


 try { keycloak = getKeycloakInstance(); List<UserRepresentation> userRepresentations = keycloak.realm(env.getProperty("keycloak.realm")).users().list(); } catch (Exception e) { e.printStackTrace(); } finally { if (keycloak != null) { keycloak.close(); } }

Quá đơn giản đúng không, các bạn nhớ phải gọi keycloak.close(); để đóng instance sau khi call xong nhé

3.4 Lấy user

Thường thì 1 user sẽ có thể định danh bởi 2 trường, userIduserName


Nếu lấy theo userName:
keycloak = getKeycloakInstance();
res = keycloak.realm(env.getProperty("keycloak.realm")).users().search(request.getParam()).get(0); 

Nếu lấy theo userId: các bạn không thể truyền vào id để get trực tiếp như user được, nên ở đây mình lọc ra từ danh sách user luôn ( hơi bị củ chuối):
 UserRepresentation user = new UserRepresentation(); keycloak = getKeycloakInstance(); List<UserRepresentation> userRepresentations = keycloak.realm(env.getProperty("keycloak.realm")).users().list(); for (UserRepresentation lts : userRepresentations) { if (lts.getId().equalsIgnoreCase(request.getParam())) { user = lts; break; } }

3.5 Add User

Để thêm mới một user các bạn làm như sau:
Các bạn cần có 1 model AddUserDTO như sau ( mình xài Lombok nên không có Get/Set j cả nha):


public class AddUserDTO { private String userName; private String email; private String phoneNumber; private String password; private String firstname; private String lastName;
}

Như các bạn thấy mình có 1 biến statusCode ở cuối cùng, Keycload sẽ trả về status theo chuẩn HTTP để chúng ta dễ hanlling nhé
 keycloak = getKeycloakInstance(); UsersResource userResource = keycloak.realm(env.getProperty("keycloak.realm")).users(); CredentialRepresentation credential = Credentials .createPasswordCredentials(request.getPassword()); UserRepresentation user = new UserRepresentation(); user.setUsername(request.getUserName()); user.setFirstName(request.getFirstname()); user.setLastName(request.getLastName()); user.setEmail(request.getEmail()); user.setCredentials(Collections.singletonList(credential)); user.setEnabled(true); Response res = userResource.create(user); int statusCode = res.getStatus(); 

3.6 Update User

Để update một user các bạn làm như sau:
Cần Model UpdateUserDTO như sau:

public class UpdateUserDTO { private String userId; private String userName; private String email; private String phoneNumber; private String password; private String firstname; private String lastName;
}

Làm thôi

 UsersResource userResource = keycloak.realm(env.getProperty("keycloak.realm")).users(); CredentialRepresentation credential = Credentials .createPasswordCredentials(request.getPassword()); UserRepresentation user = new UserRepresentation(); user.setUsername(request.getUserName()); user.setFirstName(request.getFirstname()); user.setLastName(request.getLastName()); user.setEmail(request.getEmail()); user.setCredentials(Collections.singletonList(credential)); userResource.get(request.getUserId()).update(user);

3.7 Remove User

 UsersResource userResource = keycloak.realm(env.getProperty("keycloak.realm")).users(); UserRepresentation user = new UserRepresentation(); userResource.get(userId).remove();

4 Các thao tác quan trọng khác


Khi thao tác với user không chỉ CRUD là đủ, các bạn cần set quyền hạn ( Role), set trạng thái ( enable/disable), thêm các attribute cho user
Mình sẽ hướng dẫn về trạng thái và attribute, còn role sẽ để bài sau nhé:

Trạng thái của user


Data của khách hàng là cực kì quan trọng, do đó trên thực tế việc remove ít khi được thực hiện, thay vào đó người ta thường chuyển trạng thái hoạt động về disable
Cho nên các bạn chỉ cần set trạng thái của user về disable là user đó sẽ không thể đăng nhập hệ thống được nữa:
 user.setEnabled(false);

Attribute của user

Trên thực tế các thông tin khi tạo mới user bao gồm fistName, lastName, email là không đủ. Các bạn cần thêm một số trường như SĐT, Địa chỉ.......
Vậy các bạn làm như sau (:
Ở bước thêm mới:

//tạo mới mapp Attribute Map<String, List<String>> attribute = new HashMap<>(); //tạo các attribute List<String> phone = Arrays.asList(request.getPhoneNumber()); List<String> mobileDevice = Arrays.asList(request.getMobileDevice()); //đẩy vào Map attribute.put(Constants.PHONE_NUMBER, phone); attribute.put(Constants.DEVICE, device); attribute.put(Constants.MOBILE_DEVICE, mobileDevice); //set att user.setAttributes(attribute); 

Ở bước Update các bạn cần lấy ra attribute cũ và cập nhật lại giá trị cần xử lý thôi nhé, làm như bước tạo mới là nó clear cả dữ liệu không cần update đó
Note: Kiểu dữ liệu của attribute là varchar(255) 😃 nên các bạn muốn lưu j dài hơn nhớ thay đổi trong db của Keycload nhé

5 Tóm tắt bài viết

Bài viết này mình hướng dẫn các bạn tạo user và các thao tác với user của Kecload thông qua Spring boot. Hi vọng có thể giúp đỡ được các bạn trong quá trình làm việc.
Có sai sót ở đâu các bạn giúp đỡ mình nhé

Tham khảo:
https://huongdanjava.com/vi/keycloak
https://www.baeldung.com/spring-boot-keycloak
https://medium.com/teamarimac/how-to-secure-spring-boot-application-with-keycloak-3ffed7e500a4

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tổng hợp các bài hướng dẫn về Design Pattern - 23 mẫu cơ bản của GoF

Link bài viết gốc: https://gpcoder.com/4164-gioi-thieu-design-patterns/. Design Patterns là gì. Design Patterns không phải là ngôn ngữ cụ thể nào cả.

0 0 270

- vừa được xem lúc

Học Spring Boot bắt đầu từ đâu?

1. Giới thiệu Spring Boot. 1.1.

0 0 255

- vừa được xem lúc

Cần chuẩn bị gì để bắt đầu học Java

Cần chuẩn bị những gì để bắt đầu lập trình Java. 1.1. Cài JDK hay JRE.

0 0 35

- vừa được xem lúc

Sử dụng ModelMapper trong Spring Boot

Bài hôm nay sẽ là cách sử dụng thư viện ModelMapper để mapping qua lại giữa các object trong Spring nhé. Trang chủ của ModelMapper đây http://modelmapper.org/, đọc rất dễ hiểu dành cho các bạn muốn tìm hiểu sâu hơn. 1.

0 0 179

- vừa được xem lúc

[Java] 1 vài tip nhỏ khi sử dụng String hoặc Collection part 1

. Hello các bạn, hôm nay mình sẽ chia sẻ về mẹo check String null hay full space một cách tiện lợi. Mình sẽ sử dụng thư viện Lớp StringUtils download file jar để import vào thư viện tại (link).

0 0 55

- vừa được xem lúc

Deep Learning với Java - Tại sao không?

Muốn tìm hiểu về Machine Learning / Deep Learning nhưng với background là Java thì sẽ như thế nào và bắt đầu từ đâu? Để tìm được câu trả lời, hãy đọc bài viết này - có thể kỹ năng Java vốn có sẽ giúp bạn có những chuyến phiêu lưu thú vị. DJL là tên viết tắt của Deep Java Library - một thư viện mã ng

0 0 122