Spring Boot සහ LDAP: ආරක්ෂිත පිවිසුම් විසඳුම් | SC Guide

Spring Boot Application වලට LDAP හරහා Authentication එකතු කරමු!
ආයුබෝවන් යාළුවනේ!
Software Engineering කියන්නේ දවසින් දවස අලුත් වෙන, ගොඩක් රසවත් ක්ෂේත්රයක්. මේ ක්ෂේත්රයේදී අපි Application හදනකොට User Authentication කියන එක අත්යවශ්ය දෙයක්. මොකද, අපේ System එකට අනවසර පුද්ගලයන් ඇතුළු වෙන එක වළක්වන්න ඕනනේ. පොඩි Applications වලට සාමාන්යයෙන් Database එකේ usersලා තියාගෙන authentication කරනවා. ඒක ලේසියි, වැඩේ ඉක්මනට කරගන්න පුළුවන්.
ඒත්, ඔයාලා හිතන්නකෝ, ලොකු ආයතනයක System එකකට, thousands of usersලා manage කරන්න ඕන වුණාම මොකද කරන්නේ කියලා? හැමෝමගෙම credentials අපේ Application එකේ Database එකේ තියාගෙන ඉන්න එක Practical නෑ. ඒ වගේම, එතකොට User management එකත් ගොඩක් අමාරු වෙනවා. අන්න ඒ වගේ වෙලාවට තමයි Lightweight Directory Access Protocol, නැත්නම් කෙටියෙන් LDAP කියන මේ Technology එක අපිට උදව් වෙන්නේ. මේකේදී User Information, Groups, Permissions වගේ දේවල් Centralized Directory එකක තියෙන නිසා, ගොඩක් Usersලා ඉන්න System එකකට Authentication සහ Authorization Manage කරන එක පහසු වෙනවා.
අද අපි මේ ලිපියෙන් කතා කරන්නේ Spring Boot Application එකක් LDAP server එකකට connect කරලා User Authentication කරන්නේ කොහොමද කියලා. මේක ඔයාලගේ Enterprise-level Applications හදනකොට ගොඩක් වැදගත් වෙයි. එහෙනම්, අපි පටන් ගමු!
LDAP කියන්නේ මොකද්ද? (What is LDAP?)
LDAP කියන්නේ Standard, Open, Vendor-neutral Application Protocol එකක්. මේක ප්රධාන වශයෙන්ම use කරන්නේ Distributed Directory Information Service වලට Access කරන්න. සරලව කිව්වොත්, network එකක් ඇතුලේ ඉන්න Users, Groups, Devices, සහ වෙනත් Network Resources වල Information Centralized විදිහට Store කරලා Management කරන්න තමයි මේක පාවිච්චි කරන්නේ.
Windows Active Directory, OpenLDAP, Apache Directory Server වගේ ඒවා මේ LDAP Protocol එක Use කරන Directory Services. මේවා Tree Structure එකක් වගේ තමයි Organization එකේ Data Store කරන්නේ. LDAP Entry එකක් කියන්නේ Information set එකක්. මේ හැම Entry එකකටම Unique Name එකක් තියෙනවා, ඒකට කියන්නේ Distinguished Name (DN) කියලා. DN එක හැදෙන්නේ Relative Distinguished Name (RDN) කීපයක් එකතු වෙලා.
උදාහරණයක් විදිහට, uid=john.doe,ou=people,dc=example,dc=org
කියන DN එකේ,
uid=john.doe
කියන්නේ RDN එකක්.ou=people
කියන්නේ Organizational Unit එකක් (මිනිසුන් ඉන්න තැන).dc=example,dc=org
කියන්නේ Domain Components (Domain Name එක).
මේ LDAP Server එකේ තියෙන Data Security එකට ගොඩක් වැදගත්. මොකද, හැමෝමගෙම User information එක තියෙන්නේ එක තැනක නිසා, ඒක Manage කරන්න සහ Update කරන්න ලේසියි. ඒ වගේම, Single Sign-On (SSO) වගේ දේවල් Implement කරන්නත් LDAP අපිට උදව් වෙනවා.
Spring Boot වලට LDAP ගේමුද? (Bringing LDAP to Spring Boot)
Spring Boot කියන්නේ Java Application Development වලට නම් රජා වගේ. ඒක Complex Integrations Simplify කරන්න ගොඩක් දක්ෂයි. Spring Security Framework එකත් එක්ක එකතු වෙලා LDAP Authentication කරන්න පුළුවන්. මේකේ විශේෂත්වය තමයි අඩු Code වලින්, ඉක්මනින් Configure කරන්න පුළුවන් වීම.
Spring Security මගින් LDAP Authentication වලට අවශ්ය Library සහ Configuration Options සපයනවා. අපිට කරන්න තියෙන්නේ නිවැරදි Dependencies එකතු කරලා, application.properties
එකේ හෝ Java Config එකෙන් අවශ්ය Configuration ටික දාන එක විතරයි. එතකොට අපේ Application එකට එන Requests වල Usersලව Validate කරන්න පුළුවන් LDAP Server එක හරහා.
පියවරෙන් පියවර LDAP Integration (Step-by-Step LDAP Integration)
හරි, දැන් අපි බලමු කොහොමද Spring Boot Application එකකට LDAP Authentication එකතු කරන්නේ කියලා.
1. Project Setup
මුලින්ම Spring Initializr (https://start.spring.io/
) එකට ගිහින් අලුත් Spring Boot Project එකක් හදාගමු. මේ සඳහා පහත Dependencies ටික තෝරන්න:
- Spring Web: Web Application එකක් හදන්න.
- Spring Security: Authentication සහ Authorization සඳහා.
- Spring LDAP: LDAP Protocol එක එක්ක වැඩ කරන්න.
මම මෙතනදි Maven Project එකක් තෝරනවා. Project එක Generate කරලා, Download කරලා, ඔයාලා කැමති IDE එකක (IntelliJ IDEA, VS Code වගේ) Open කරගන්න.
2. Dependencies Add කිරීම
pom.xml
(Maven නම්) හෝ build.gradle
(Gradle නම්) file එකේ මේ Dependencies තියෙනවද කියලා Check කරන්න. නැත්නම් පහත විදිහට එකතු කරගන්න.
pom.xml (Maven):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<!-- Embedded LDAP server for testing/development -->
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
unboundid-ldapsdk
කියන එක Development Purposes වලට Embedded LDAP Server එකක් විදිහට පාවිච්චි කරන්න පුළුවන්. ඒකෙන් අපිට Local Test Environment එකක් හදාගන්න පුළුවන්, Real LDAP Server එකක් නැතුව වුණත්.
3. application.properties Configuration
දැන් src/main/resources/application.properties
file එක Open කරලා පහත Configurations එකතු කරන්න.
application.properties:
# Embedded LDAP Configuration (for development/testing)
# Spring Boot automatically starts an embedded LDAP server based on these properties
spring.ldap.embedded.port=8389
spring.ldap.embedded.ldif=classpath:test-ldap-server.ldif
spring.ldap.embedded.base-dn=dc=springframework,dc=org
# Spring Security LDAP Configuration
# This tells Spring Security how to connect to the LDAP server and authenticate users
spring.security.authentication.ldap.urls=ldap://localhost:8389/
spring.security.authentication.ldap.base=dc=springframework,dc=org
# Manager DN and password for binding to LDAP (if required for searching)
# This user needs sufficient permissions to search the directory
spring.security.authentication.ldap.manager-dn=uid=admin,ou=system
spring.security.authentication.ldap.manager-password=secret
# User Search Configuration
# user-search-base: The base DN for user searches (e.g., where your users are located)
# user-search-filter: The filter used to find a user by their username (e.g., uid={0} for username)
spring.security.authentication.ldap.user-search-base=ou=people
spring.security.authentication.ldap.user-search-filter=(uid={0})
# Group Search Configuration (Optional, for roles/authorities)
# group-search-base: The base DN for group searches
# group-search-filter: The filter used to find groups a user belongs to
# group-role-attribute: The attribute in the group entry that holds the role name (e.g., cn for common name)
spring.security.authentication.ldap.group-search-base=ou=groups
spring.security.authentication.ldap.group-search-filter=(uniqueMember={0})
spring.security.authentication.ldap.group-role-attribute=cn
# Logging configuration for debugging LDAP issues
logging.level.org.springframework.security=DEBUG
logging.level.org.springframework.ldap=DEBUG
logging.level.com.unboundid=DEBUG
test-ldap-server.ldif
File එක
src/main/resources/
folder එක ඇතුලේ test-ldap-server.ldif
කියලා file එකක් හදලා, පහත content එක ඒකට දාන්න. මේක Embedded LDAP Server එකේ Initial Data Set එක.
dn: dc=springframework,dc=org
objectClass: top
objectClass: domain
dc: springframework
dn: ou=system,dc=springframework,dc=org
objectClass: organizationalUnit
ou: system
dn: uid=admin,ou=system,dc=springframework,dc=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: Administrator
sn: Admin
uid: admin
userPassword: secret
dn: ou=people,dc=springframework,dc=org
objectClass: top
objectClass: organizationalUnit
ou: people
dn: ou=groups,dc=springframework,dc=org
objectClass: top
objectClass: organizationalUnit
ou: groups
dn: uid=user1,ou=people,dc=springframework,dc=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: User One
sn: One
uid: user1
userPassword: {bcrypt}$2a$10$dXmG71kHqD0qBfL8U2YJm.2V1r/s.m.0/J5R/j/1V5G5S0y0t.2
dn: uid=user2,ou=people,dc=springframework,dc=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: User Two
sn: Two
uid: user2
userPassword: {bcrypt}$2a$10$dXmG71kHqD0qBfL8U2YJm.2V1r/s.m.0/J5R/j/1V5G5S0y0t.2
dn: cn=developers,ou=groups,dc=springframework,dc=org
objectClass: top
objectClass: groupOfUniqueNames
cn: developers
uniqueMember: uid=user1,ou=people,dc=springframework,dc=org
dn: cn=qa,ou=groups,dc=springframework,dc=org
objectClass: top
objectClass: groupOfUniqueNames
cn: qa
uniqueMember: uid=user2,ou=people,dc=springframework,dc=org
සැලකිය යුතුයි: userPassword
attribute එකේ තියෙන්නේ BCrypt Encoded Password එකක්. {bcrypt}
prefix එකෙන් කියවෙන්නේ Spring Security එකට මේක BCrypt වලින් Encode කරපු එකක් කියලා. user1
සහ user2
දෙන්නාගේම password එක password
කියලා දාන්න පුළුවන්.
4. Security Configuration Class
දැන් අපි Spring Security Configure කරන Class එක හදමු. Project එකේ Main Package එක ඇතුලේ SecurityConfig.java
කියලා Class එකක් හදලා පහත Code එක එකතු කරන්න.
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDnPatterns("uid={0},ou=people") // How to construct the DN for a user from the username
.groupSearchBase("ou=groups") // Base DN for searching groups
.groupSearchFilter("uniqueMember={0}") // Filter to find groups a user belongs to
.contextSource() // Configure the LDAP connection source
.url("ldap://localhost:8389/dc=springframework,dc=org") // LDAP server URL and base DN
.managerDn("uid=admin,ou=system") // Manager DN for binding (user with search permissions)
.managerPassword("secret") // Manager password
.and()
.passwordCompare() // Configure password comparison
.passwordEncoder(new BCryptPasswordEncoder()) // The encoder used for passwords in LDAP
.passwordAttribute("userPassword"); // The attribute that holds the password in LDAP
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests() // Define authorization rules
.antMatchers("/public/**").permitAll() // Allow public access to /public/**
.anyRequest().authenticated() // All other requests require authentication
.and()
.formLogin() // Enable form-based login
.and()
.httpBasic(); // Enable HTTP Basic authentication (optional, good for API testing)
}
}
මේ Code එකේ වෙන්නේ මොකක්ද කියලා පොඩ්ඩක් බලමු:
@Configuration
සහ@EnableWebSecurity
annotations වලින් කියවෙන්නේ මේ Class එක Spring Security Configuration එකක් කියලා.configure(AuthenticationManagerBuilder auth)
method එකේදී අපි LDAP Authentication Configure කරනවා..userDnPatterns("uid={0},ou=people")
: මේකෙන් කියන්නේ User Name එකක් දුන්නම User ගේ DN එක හදාගන්නේ කොහොමද කියලා. උදාහරණයක් විදිහට,user1
කියලා දුන්නමuid=user1,ou=people,dc=springframework,dc=org
කියලා හදාගන්නවා..groupSearchBase("ou=groups")
: Group Searches පටන් ගන්න ඕනෙ Base DN එක..groupSearchFilter("uniqueMember={0}")
: User කෙනෙක්ට අදාළ Groups හොයන Filter එක.{0}
කියන තැනට User ගේ සම්පූර්ණ DN එක එනවා..contextSource()
: LDAP Server එකට Connect වෙන්න අවශ්ය Information (URL, Manager DN, Manager Password) මෙතනින් දෙනවා.managerDn
සහmanagerPassword
කියන්නේ LDAP Server එකේ Usersලා Search කරන්න පුළුවන් Permission තියෙන User කෙනෙක්ගේ Credentials..passwordCompare().passwordEncoder(new BCryptPasswordEncoder()).passwordAttribute("userPassword")
: LDAP එකේ තියෙන Passwords Compare කරන්නේ කොහොමද කියලා මේකෙන් කියනවා. අපි මෙතන BCryptEncoder එකක් පාවිච්චි කරලා, Password එක තියෙන්නේuserPassword
කියන Attribute එකේ කියලා කියනවා.
configure(HttpSecurity http)
method එකේදී අපි URL Based Authorization Rules Define කරනවා..anyRequest().authenticated()
: හැම Request එකකටම Authentication ඕන කියලා කියනවා..formLogin()
: Form-based Login එකක් Enable කරනවා..httpBasic()
: Basic HTTP Authentication එකක් Enable කරනවා. (Postman වගේ Tools වලින් Test කරන්න ගොඩක් හොඳයි).
5. Test Controller
දැන් අපි සාර්ථකව Login වුණාද කියලා බලන්න පොඩි RestController එකක් හදමු. src/main/java/com/example/ldapexample/
(ඔයාලගේ package name එක) යටතේ HelloController.java
කියලා Class එකක් හදලා පහත Code එක එකතු කරන්න.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
@RestController
public class HelloController {
@GetMapping("/")
public String home() {
return "ආයුබෝවන්! සාර්ථකව පිවිසුනා!"; // Welcome! Successfully logged in!
}
@GetMapping("/user-info")
public String userInfo(Principal principal) {
if (principal != null) {
return "ඔබ <strong>" + principal.getName() + "</strong> ලෙස පිවිස ඇත."; // You are logged in as X.
}
return "පිවිස නැත."; // Not logged in.
}
@GetMapping("/public/hello")
public String publicHello() {
return "මේක Public Access තියෙන Endpoint එකක්!";
}
}
ප්රායෝගික උපදෙස් සහ ගැටලු නිරාකරණය (Practical Tips & Troubleshooting)
- Embedded LDAP Server: අපි මේ Project එකේදී
unboundid-ldapsdk
එක පාවිච්චි කරලා Embedded LDAP Server එකක් පාවිච්චි කළා. මේක Development සහ Testing වලට ගොඩක් පහසුයි. Real LDAP Server එකක් නැතිව වුණත් ඔයාලට මේක Try කරන්න පුළුවන්. - LDAP Client Tools: LDAP Server එකේ Data බලන්න සහ Modify කරන්න Apache Directory Studio, JXplorer වගේ Tools පාවිච්චි කරන්න පුළුවන්. මේවා Free Tools. මේවායින් ඔයාලට DNs, Attributes හරිද කියලා Check කරන්න පුළුවන්.
- Logging:
application.properties
එකේlogging.level.org.springframework.security=DEBUG
සහlogging.level.org.springframework.ldap=DEBUG
කියලා දාපු නිසා Console එකේ Login Process එකේ හැම Step එකක්ම බලාගන්න පුළුවන්. මොකක් හරි Error එකක් ආවොත් මේ Logging වලින් Reason එක හොයාගන්න ලේසියි. - Common Issues:
- Incorrect DNs/Passwords:
userDnPatterns
,groupSearchBase
,managerDn
වගේ ඒවායේ වැරදි තියෙන්න පුළුවන්. හොඳට Check කරන්න. Passwords හරිද බලන්න. - Firewall Issues: LDAP Port එක (සාමාන්යයෙන් 389 හෝ 636 for LDAPS) Firewall එකෙන් Block වෙලා තියෙන්න පුළුවන්.
- SSL/TLS Problems: Production එකේදී සාමාන්යයෙන් LDAPS (LDAP over SSL/TLS) පාවිච්චි කරනවා. ඒ වෙලාවට Certificates හරි විදිහට Configure වෙලා තියෙන්න ඕනේ.
- Password Encoding: LDAP Server එකේ Passwords Store කරලා තියෙන Encoding Format එක (BCrypt, SSHA, plain text) හරි විදිහට Spring Security එකට කියන්න ඕනේ.
- Incorrect DNs/Passwords:
අවසන් වශයෙන් (Conclusion)
අද අපි Spring Boot Application එකක් LDAP Server එකකට connect කරලා User Authentication සකසන හැටි ඉගෙන ගත්තා. මේක Enterprise-level Applications වලට ගොඩක් වැදගත්. මොකද, usersලා දහස් ගණන් Manage කරන එකට මේ වගේ Centralized Authentication Solution එකක් අත්යාවශ්යයි.
මේ ලිපියේ තියෙන පියවර ටික ඔයාලත් ඔයාලගේ Machine එකේ Try කරලා බලන්න. Code එක Run කරලා user1
සහ password
(හෝ user2
සහ password
) වලින් Login වෙලා බලන්න. ප්රශ්න තියෙනවා නම්, Code එකේ මොනවා හරි අවුලක් තියෙනවා නම්, එහෙමත් නැත්නම් ඔයාලගේ අදහස් තියෙනවා නම්, පහළ Comment Section එකේ අනිවාර්යයෙන්ම දාන්න. මම පුළුවන් ඉක්මනට උත්තර දෙන්නම්.
ඉදිරියේදී තවත් මේ වගේ වැදගත් Topics ගැන කතා කරමු. එහෙනම්, ඊළඟ ලිපියකින් හමුවෙමු! Happy Coding!