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

Cài đặt Apache Directory Studio và cấu hình LDAP với Spring data ldap sử dụng Spring Boot - Elasticsearch -Thymeleaf

0 0 69

Người đăng: Kien Pham

Theo Viblo Asia

Trong bài viết này tôi hướng dẫn các bạn cấu hình LDAP với Spring Boot:

Công cụ và thư viện được sử dụng trong bài viết:

  • Spring boot 2.7.4
  • Spring tool suite 4
  • Spring data elasticsearch 4.4.2
  • Maven 3
  • Java 11
  • Elasticsearch 7.17.6
  • Kaizen Elastic
  • Apache Directory Studio(2.0.0-M17)
  • ApacheDS(2.0.0.AM26)

1. Cấu trúc project:

2. Cấu trúc file pom:

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>ldap</artifactId> <version>0.0.1-SNAPSHOT</version> <name>ldap</name> <description>Demo project for Spring Boot</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-ldap</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.ldap</groupId> <artifactId>spring-ldap-core</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

3. Apache Directory Studio:

Đầu tiên, cần tải về "Apache Directory Studio". Link download:

https://directory.apache.org/studio/download/download-windows.html

Ở đây tôi tải bản mới nhất cho window, tôi chọn file mở rộng là ".exe"

Sau khi cài đặt thành công Apache Directory Studio -> mở ứng dụng lên. Nếu bạn nào gặp thông báo lỗi "Incompatible JVM" thì có nghĩa là hiện tại phiên bản java các bạn đang sử dụng thấp hơn yêu cầu mà Apache Directory Studio yêu cầu. Phiên bản mới nhất yêu cầu Java tối thiểu là version 11

Để giải quyết vấn đề này các bạn cần cài đặt Java version 11 trở lên, ở đây tôi tải bản Java 11 và chọn file mở rộng là ".exe":

Link download: https://www.oracle.com/java/technologies/javase/jdk11-archive-downloads.html

Sau khi cài đặt thành công -> đường dẫn mặc định là: "C:\Program Files\Java\jdk-11.0.16\bin"

Các bạn tiến hành cập nhật lại biến môi trường cho Java phiên bản mới, xong mở Command Prompt lên và kiểm tra version đúng chưa:

Nhưng nếu bạn nào gặp vấn đề sau khi nâng cấp thành công, kiểm tra version cũng thấy đã cập nhật đến Java phiên bản mới nhưng khi mở ứng dụng Apache Directory Studio vẫn bán lỗi "Incompatible JVM" thì xử lý như sau:

Các bạn vào thư mục của Apache Directory Studio, mặc định là: "C:\Program Files\Apache Directory Studio"

Trong thư mục Apache Directory Studio, mở file "ApacheDirectoryStudio.ini", tìm tới dòng:

#-vm
#/usr/lib/jvm/java-11-openjdk/bin/java

Cập nhật lại dòng "/usr/lib/jvm/java-11-openjdk/bin/java" -> đường dẫn chứa Java:

"/usr/lib/jvm/java-11-openjdk/bin/java" -> "C:\Program Files\Java\jdk-11.0.16\bin"

Sau khi cập nhật lại đường dẫn -> bỏ comment ra để sử dụng

Tôi mở Apache Directory Studio lên:

=> Mở ứng dụng thành công

Tiếp theo, tôi tạo 1 new "Connection", trong mục "Connections" click phải chuột và chọn "New Conection...":

Tại giao diện "Connection" -> cấu hình các mục như bên dưới:

  • Connection name: Tuỳ ý. Ở đây tôi để là "LdapProject"
  • Hostname: Tôi để "localhost"
  • Port: Tôi để "10389"
  • Connection timeout (s): Tôi để "300"

Giao diện "Authentication":

  • Bind Dn or user: Tôi để "uid=admin,ou=system"
  • Password: Tôi để "secret"

Tiếp theo, click "Finish" -> nó sẽ báo lỗi "cannot_connect_to_server" lý do là chưa cài đặt ApacheDS, tiến hành cài đặt ApacheDS:

Link download: https://directory.apache.org/

Ở đây tôi tải bản mới nhất version "2.0.0.AM26", tôi chọn tải bản ".zip":

Sau khỉ tải về, tiến hành giải nén và trong thư mục vừa giải nén tìm đến file "apacheds.bat: -> run file này để start:

Sau khi start xong, quay lại giao diện LDAP, click phải chuột vào "Connection" vừa tạo -> chọn "Open connection" hoặc double click vào tên connection

=> Start thành công

Sau khi chuẩn bị xong cho phần cài đặt Apache Directory Studio, tôi qua tiếp phần cấu hình Ldap trong Spring Boot

4. Nội dung file application:

Ở đây, tôi có enable SSL để cấu hình sử dụng HTTP/2, trong bài viết này không cần cấu hình SSL, các bạn có thể tham khảo làm thế nào để enable SSL và HTTP/2:

https://viblo.asia/p/tao-mot-project-voi-spring-boot-thymeleaf-elasticsearch-su-dung-http2-tao-service-run-elasticsearch-yZjJYjolLOE

5. Package "com.example.ldap.application":

6. Package "com.example.ldap.model":

Trong package này tôi tạo 1 class "User":

Nội dung class "User": Class này tôi sử dụng để khai báo repository cho Elasticsearch

7. Package "com.example.ldap.repository":

Trong package này tôi tạo 1 class "UserESRepository" :

**Nội dung class "UserESRepository": **

8. Package "com.example.ldap.service":

Nội dung class "ILdapService":

Nội dung class "LdapService":

9. Package "com.example.ldap.controller":

Trong controller, đầu tiên tôi tạo 1 mapping để load page đăng nhập:

Tiếp theo, tôi cần tạo 1 mapping "/createUser" để xử lý việc thêm mới user và lưu dữ liệu trong Elasticsearch database và Ldap. Tại Ldap tôi cũng lưu những thông tin cơ bản của user gồm "userId - firstName - lastName - email - password". Tôi không lưu thông tin password trong database ES nữa, thay vào đó tôi dùng Ldap để quản lý thông tin password

Phương thức "createUser" trong LdapService:

Trước tiên, tôi giới thiệu qua 1 vài thuộc tính phổ biến trong Ldap mà tôi sử dụng trong bài viết này:

  • CN(Common Name): Firstname + Lastname và thuộc tính này là bắt buộc

  • DN(distinguishedName): Trong file application.xml tôi có khia báo 1 thuộc tính "spring.ldap.base" với giá trị mặc định là "dc=example,dc=com" -> đây là DN. Ví dụ, tôi có 1 "ou=users" -> DN sẽ là "ou=users,dc=example,dc=com"

  • SN(Lastname)

  • OU(Organizational unit): Tôi lấy ví dụ đơn giản như này. Bạn tạo 1 OU là "useraccounts" trong "dc=example,dc=com" và trong OU đó quản lý nhiều tài khoản user

     dc=example,dc=com ou=useraccounts cn=user001
    

Tôi đi phân tích những phần chính trong phương thức "createUser":

Trong đoạn code ở trên, tôi khai báo đường dẫn DN mà tôi sẽ thêm user vào:

dc=example,dc=com ou=users cn=user001(đây là user tôi sẽ tạo)

Trong đoạn code trên, tôi thêm thuộc tính "objectclass""person", tôi lấy ví dụ trực tiếp trên Apache Directory Studio cho dễ hiểu:

Tại Apache Directory Studio, tại màn hình "Attribute Description" tôi phải chuột và chọn "New Attribute...":

Tại mục "Attribute type" tôi chọn "objectClass" -> click "Finish":

Tại mục "Available object classes" tôi chọn "person" như trong code tôi khai báo và tôi click "Add" -> click "Next":

Tại giao diện "Attributes", các bạn thấy có thêm 2 thuộc tính cần phải nhập dữ liệu là "CN" và "SN" nên trong phương thức "createUser" tôi có thêm 2 thuộc tính đó, giá trị "CN" tôi lấy theo giá trị userId

Tiếp theo, tôi lấy ví dụ cho 1 loại object class khác là "account", quay về giao diện "Object classes" tôi remove "person" đã thêm trước đó ra và chọn "account" -> click "Add" -> click "Next":

=> Các bạn thấy, với object class là "account" -> nó không có 2 thuộc tính là bắt buộc là "CN" và "SN" thay vào đó là thuộc tính "UID", nên tuỳ theo lạoi objectClass mà cần phải khai báo các thuộc tính bắt buộc cho phù hợp

Trong phương thức "createUser" tôi có khai báo thuộc tính "userPassword", thuộc tính này dùng để lưu thông tin password user và tôi đã có mã hoá password truyền vào với phương thức "encodeToSHA":

Trong class "LdapService" tôi sử dụng phương thức "getUserLdap" dùng để lấy ra thông tin user lưu trong Ldap dựa vào DN:

Tôi sử dụng "ldapTemplate.lookup(dn)" tìm kiếm theo DN -> nó sẽ trả về 1 single object nếu tìm thấy, ví dụ tôi đang có thông tin user001 như bên dưới:

dc=example,dc=com ou=users cn=user001

Nếu tôi muốn tìm user001 -> DN lúc này là "cn=user001,ou=users,dc=example,dc=com" nghĩa là tìm trong "dc=example,dc=com" trong "ou=users" có thông tin user nào với "cn=user001" hay không

Trong controller, tôi tạo phương thức "getUserLdap":

Tiếp theo, tôi quay lại Controller với mapping "/createUser":

Trong phương thức này, tôi lưu thông tin user đến ES và Ldap

Thông tin password tôi thiết lập theo mẫu: "P@ssword" + birthDate(yyyyMMdd), ví dụ birthDate của user là "01-01-1986" -> password sẽ là "P@ssword19860101"

Bây giờ, tôi tiến hành kiểm tra với kịch bản tạo 1 user với nội dung:

{ "userId":"user001", "firstName":"visible", "lastName":"mask", "email": "abc@example.com", "address": "tphcm", "birthDate":"1986-01-01
}

Tôi dùng Postman call api "https://localhost:8080/createUser", method là "POST":

=> Kết quả không tạo được user

Tôi kiểm tra console log, thấy báo lỗi này:

Nguyên nhân gây ra lỗi này là do trong code tôi có khai báo "ou=users" nhưng hiện tại kiểm tra trong DN "dc=example,dc=com" không có "ou=users".Tôi chạy Apache Directory Studio kiểm tra lần nữa:

=> Không có "ou=users" trong DN "dc=example,dc=com"

Vậy tôi chỉ cần tạo 1 "ou=users" là xong, tôi giới thiệu 2 cách để thêm "ou=users":

Cách 1: Nhanh nhất, các bạn thấy mặc định có "ou=system", bung cây thư mục ra và tìm đến bất kỳ ou nào, ở đây tôi thấy có "ou=users" -> copy entry này và paste đến DN "dc=example,dc=com":

Khi paste entry vào, sẽ có thông báo hỏi, các bạn chọn option đầu tiên:

Như vậy, đã có "ou=users" trong DN "dc=example,dc=com":

Cách 2: Tạo 1 file định dạng "*.ldif" với nội dung:

Tại Apache Directory Studio -> chọn File -> New hoặc nhấn tổ hợp phím "Ctrl + N".Tại giao diện "Select a wizard" -> bung cây thư mục "LDAP Bowser" ra và chọn "LDIF File" -> click "Finish":

Tôi tạo nội dung như bên dưới và save file này

dn: ou=users,dc=example,dc=com
objectClass: organizationalUnit
ou: users

Tôi khai báo "ou=users" nghĩa là khi tôi import file này đến DN "dc=example,dc=com" -> "ou=users" sẽ được tạo, các bạn có thể tuỳ ý tạo ou với tên khác nhau

Để import ldif file, click phải chuột vào DN "dc=example,dc=com" -> chọn "Import" -> chọn "LDIF Import..." -> chọn đến nơi chứa file ldif vừa tạo -> click "Finish":

Các bạn cần chú ý 1 vấn đề, nếu những lần sau các bạn import lại chính file trước đó đã import -> sẽ báo lỗi và lúc này chỉ cần check chọn option "Overwrite existing logfile" rồi click "Finish":

Tôi call api "https://localhost:8080/createUser" để kiểm tra:

=> Tạo user thành công trong Es và Ldap

Kiểm tra trong Elasticsearch:

Kiểm tra trong Ldap, để reload entry nhấn "F5" hoặc chuột phải DN -> chọn "Reload Entry":

=> user001 được lưu thành công đến Ldap

Sau khi tạo user thành công, tôi xử lý tiếp cho phương thức "checkInfoUserLogin" trong controller:

Trong phương thức "checkInfoUserLogin" tôi có sử dụng phương thức "authenticate" từ class "LdapService" để kiểm userId với password có trong Ldap không:

Để kiểm tra, tôi phải khai báo đường dẫn DN, ở đây DN là "cn={userId},ou=users,dc=example,dc=com"

Tôi thử đăng nhập trang web với thông tin userId: "user001" và password là "P@ssword19860101":

=> Đăng nhập thành công và redirect đến dashboard

Tôi kiểm tra với kịch bản tạo mới với userId đã có:

=> Tạo mới không thành công

Kiểm tra tiếp với kịch bản tạo 1 user khác, ở đây tôi tạo "user002":

{ "userId":"user002", "firstName":"mr", "lastName":"bear", "email": "bear@example.com", "address": "tphcm", "birthDate":"1988-04-01" }

=> Tạo mới thành công

Kiểm tra trong ES:

=> Lưu data thành công

Kiểm tra trong Ldap:

=> Lưu data thành công

Tôi thử đăng nhập với userId là user002:

=> Đăng nhập thành công

Bình luận

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

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

Elasticsearch là gì ?

. Lời nói đầu. Elasticsearch là gì .

0 0 35

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

Backup và Restore Elasticsearch snapshot với AWS S3 trong Kubernetes

Ở công ty mình vừa có mấy task devops liên quan đến scaling, clustering Elasticsearch nên viết lại đề phòng sau này cần dùng. Có một task là chuyển dữ liệu từ single-node Elasticsearch cũ lên cluster mới.

0 0 50

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

Reindex Elasticsearch data with zero downtime

Elasticsearch là một search engine tuyệt vời cho mọi dự án muốn áp dụng chức năng search cho sản phẩm của mình, với những tính năng như là near-realtime search, auto-complete, suggestion,.... Cùng với đó là lợi thế kiến trúc distributed search system, có thể dễ dàng scaling, failing handle. Khi muốn

0 0 40

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

Fork you ElasticSearch! How Open Source Works

ElasticSearch recently dropped its open-source licensing strategy, prompting AWS to fork it. Learn how "Open Source" actually works and how companies profit from it.

0 0 48

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

Tìm hiểu Text và Keyword trong Elasticsearch

Giới thiệu. Khi mình mới bắt đầu tìm hiểu về Elasticsearch mình không nghĩ rằng giữa kiểu dữ liệu Text và Keyword có sự khác nhau nhưng khi vào dự án thực tế mình mới nhận ra được sự khác biệt giữa 2

0 0 140

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

Tìm hiểu và cài đặt Elasticsearch

Elasticsearch là gì. Elasticsearch cung cấp công cụ tìm tiếm và phân tích gần như là thời gian thực, áp dụng với mọi kiểu dữ liệu - văn bản có cấu trúc hoặc phi cấu trúc, số, thông tin địa lý.

0 0 113