Spring Security LDAP實(shí)現(xiàn)身份驗(yàn)證的項(xiàng)目實(shí)踐
如果你曾經(jīng)在生產(chǎn)級(jí)應(yīng)用程序中實(shí)現(xiàn)過(guò)登錄功能,你一定聽(tīng)說(shuō)過(guò) LDAP 身份驗(yàn)證。
LDAP 可用于任何類型的分層目錄信息,LDAP 最流行的用途是存儲(chǔ)組織數(shù)據(jù)。
舉個(gè)例子,比如說(shuō)你們公司一個(gè)典型的組織結(jié)構(gòu),那么一般都有董事、經(jīng)理、監(jiān)事等職位。這些呢就是 LDAP 機(jī)制最適合實(shí)現(xiàn)的分層數(shù)據(jù)。通過(guò)這種方式,大多數(shù)組織使用它來(lái)維護(hù)組織信息,包括其憑證。
因此,我們接下來(lái)演示一下 Spring Security LDAP 身份驗(yàn)證示例。
1、LDAP 是什么?
LDAP 代表輕量級(jí)目錄訪問(wèn)協(xié)議。它是一種開放的、供應(yīng)商中立的行業(yè)標(biāo)準(zhǔn)應(yīng)用程序協(xié)議,用于通過(guò)網(wǎng)絡(luò)訪問(wèn)和維護(hù)分布式目錄信息服務(wù)。
2、LDAP 是怎么工作的?
比如上面那個(gè)例子,LDAP 可用來(lái)存儲(chǔ)組織的用戶信息。
當(dāng)用戶嘗試登錄應(yīng)用程序時(shí),它會(huì)檢查 LDAP 以查看其是否是有效用戶以及該用戶是否具有所需的權(quán)限和有效憑據(jù)。
在 Spring Security 的上下文中,應(yīng)用程序連接到 LDAP 服務(wù)器,以便根據(jù)該 LDAP 驗(yàn)證有效用戶。
3、LDIF 是什么?
LDIF 是 LDAP 數(shù)據(jù)交換格式的縮寫。
它是文件的標(biāo)準(zhǔn)純文本數(shù)據(jù)交換格式,用于表示 LDAP 目錄內(nèi)容,文件的擴(kuò)展名是“.ldif”。
LDIF 文件中有多個(gè)字段,詳細(xì)了解一下:
3.1 LDIF 文件中有哪些常見(jiàn)字段?
1)dn:專有名稱
“dn”代表唯一標(biāo)識(shí)目錄中條目的名稱。
DN 是必填字段,如果 DN 中存在逗號(hào),則必須使用反斜杠(\)對(duì)逗號(hào)進(jìn)行轉(zhuǎn)義。例如,dn: uid=sam, ou=people, o=example.com Bolivia\,S.A.
2)o:組織
“o”代表組織名稱。例如:juejin.cn
3)dc:域分量
“dc”代表域的每個(gè)組成部分。例如 www.example.com 將寫為 DC = www, DC = example, DC = com
4)ou:組織單位
“ou”代表用戶所屬的組織單位(或有時(shí)是用戶組)。如果用戶屬于多個(gè)組,您可以通過(guò)提供多個(gè)條目來(lái)指定它。例如:OU = 員工,OU = 管理員。
5)cn:通用名
“cn”代表您正在查詢的單個(gè)對(duì)象(人名、會(huì)議室、菜譜名稱、職位等)。它是人們常用的。例如,cn:郭德綱。至少需要一個(gè)通用名稱。
6)sn:姓氏
“sn”代表人的姓氏。例如,sn:郭。需要提供姓氏。
7)objectClass:對(duì)象類
“objectClass”指定與此條目一起使用的對(duì)象類。
它是必填字段。例如:objectClass:person,objectClass:organizationalPerson。
應(yīng)包含此對(duì)象類規(guī)范,因?yàn)樵S多 LDAP 客戶端在對(duì)個(gè)人或組織人員進(jìn)行搜索操作期間需要它。
3.2 LDIF 文件的格式是什么?
LDIF 由一個(gè)或多個(gè)以空行分隔的目錄條目組成。每個(gè) LDIF 條目都包含一個(gè)可選的條目 ID、一個(gè)必需的專有名稱、一個(gè)或多個(gè)對(duì)象類以及多個(gè)屬性定義。
LDIF 格式在 RFC 2849 LDAP 數(shù)據(jù)交換格式 (LDIF) 中定義。 Sun Java System Directory Server 符合此標(biāo)準(zhǔn)。
LDIF 中表示的目錄項(xiàng)的基本形式如下:
dn: distinguished_name objectClass: object_class objectClass: object_class ... attribute_type[;subtype]:attribute_value attribute_type[;subtype]:attribute_value ...
我們必須提供 DN 和至少一個(gè)對(duì)象類定義。此外,我們必須包含為條目定義的對(duì)象類所需的任何屬性。
所有其他屬性和對(duì)象類都是可選的。我們可以按任何順序指定對(duì)象類和屬性。冒號(hào)后面的空格也是可選的。
例如,下面是 LDIF 文件中的有效條目,這里的“uid”字段代表該人的用戶 ID。
dn: uid=bob,ou=people,dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson cn: Bob Hamilton sn: Hamilton uid: bob userPassword: bobspassword
4、如何使用 Spring Boot 實(shí)現(xiàn) Spring Security LDAP 身份驗(yàn)證?
假設(shè)我們有一個(gè)應(yīng)用程序,我們已經(jīng)使用 Spring 框架提供的 Spring Security API 實(shí)現(xiàn)了基本的安全性?,F(xiàn)在我們必須實(shí)施 LDAP 身份驗(yàn)證以使其更加安全。
因此,我們需要開發(fā)一個(gè)基本的 Web 應(yīng)用程序,然后實(shí)現(xiàn) LDAP 身份驗(yàn)證概念來(lái)滿足 Spring Security LDAP 身份驗(yàn)證示例的要求。
以下是詳細(xì)步驟:
步驟1:創(chuàng)建 Spring Boot Starter 項(xiàng)目
創(chuàng)建入門項(xiàng)目時(shí),選擇“Spring Web”、“Spring LDAP”、“嵌入式 LDAP 服務(wù)器”、“Spring security”和“Spring Boot DevTools”作為入門項(xiàng)目依賴項(xiàng)。
這里“Spring Boot Dev Tools”是可選添加的。我們使用 Spring Boot Dev Tools 來(lái)實(shí)現(xiàn)熱加載,避免在測(cè)試應(yīng)用程序時(shí)多次重新啟動(dòng) tomcat 服務(wù)器。除此之外,我們還需要添加一個(gè)額外的依賴項(xiàng)“spring-security-ldap”。
以下是我們使用 Spring Boot 開發(fā)此 Spring Security LDAP 身份驗(yàn)證示例所使用的依賴項(xiàng)。
<dependency>? ? ? <groupId>org.springframework.boot</groupId>? ? ? <artifactId>spring-boot-starter-web</artifactId>? </dependency> <dependency>? ? ? <groupId>org.springframework.boot</groupId>? ? ? <artifactId>spring-boot-starter-data-ldap</artifactId>? </dependency>? <dependency>? ? ? <groupId>com.unboundid</groupId>? ? ? <artifactId>unboundid-ldapsdk</artifactId>? ? ? <!-- <scope>test</scope> -->? </dependency>? <dependency>? ? ? <groupId>org.springframework.security</groupId>? ? ? <artifactId>spring-security-ldap</artifactId>? </dependency>? <dependency>? ? ? <groupId>org.springframework.boot</groupId>? ? ? <artifactId>spring-boot-starter-security</artifactId>? </dependency>? <dependency>? ? ? <groupId>org.springframework.boot</groupId>? ? ? <artifactId>spring-boot-devtools</artifactId>? ? ? <scope>runtime</scope>? </dependency>?
步驟2:創(chuàng)建一個(gè) .ldif 文件作為 ldap-data.ldif
該文件將具有強(qiáng)制的 .ldif 擴(kuò)展名。在 src/main/resources 文件夾下創(chuàng)建一個(gè)名為“ldap-data.ldif”的文件并更新數(shù)據(jù),如下所示。
我們從 Spring 官方文檔網(wǎng)站獲取此文件。它將作為本地目錄工作,并具有兼容的數(shù)據(jù)以相應(yīng)地與 LDAP 配合使用。
dn: dc=springframework,dc=org objectclass: top objectclass: domain objectclass: extensibleObject dc: springframework dn: ou=groups,dc=springframework,dc=org objectclass: top objectclass: organizationalUnit ou: groups dn: ou=subgroups,ou=groups,dc=springframework,dc=org objectclass: top objectclass: organizationalUnit ou: subgroups dn: ou=people,dc=springframework,dc=org objectclass: top objectclass: organizationalUnit ou: people dn: ou=space cadets,dc=springframework,dc=org objectclass: top objectclass: organizationalUnit ou: space cadets dn: ou="quoted people",dc=springframework,dc=org objectclass: top objectclass: organizationalUnit ou: "quoted people" dn: ou=otherpeople,dc=springframework,dc=org objectclass: top objectclass: organizationalUnit ou: otherpeople dn: uid=ben,ou=people,dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: Ben Alex sn: Alex uid: ben userPassword: $2a$10$c6bSeWPhg06xB1lvmaWNNe4NROmZiSpYhlocU/98HNr2MhIOiSt36 dn: uid=admin,ou=people,dc=springframework,dc=org? objectclass: top? objectclass: person? objectclass: organizationalPerson? objectclass: inetOrgPerson? cn: Admin? sn: Admin? uid: admin? userPassword: $2a$10$ODZhWAyD0i8zruWQcMYx9ePkW2xXsqIljhh4K8spSOUCY897ERkwu dn: uid=bob,ou=people,dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: Bob Hamilton sn: Hamilton uid: bob userPassword: bobspassword dn: uid=joe,ou=otherpeople,dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: Joe Smeth sn: Smeth uid: joe userPassword: joespassword dn: cn=mouse, jerry,ou=people,dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: Mouse, Jerry sn: Mouse uid: jerry userPassword: jerryspassword dn: cn=slash/guy,ou=people,dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: slash/guy sn: Slash uid: slashguy userPassword: slashguyspassword dn: cn=quote"guy,ou="quoted people",dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: quote"guy sn: Quote uid: quoteguy userPassword: quoteguyspassword dn: uid=space cadet,ou=space cadets,dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: Space Cadet sn: Cadet uid: space cadet userPassword: spacecadetspassword dn: cn=developers,ou=groups,dc=springframework,dc=org objectclass: top objectclass: groupOfUniqueNames cn: developers ou: developer uniqueMember: uid=ben,ou=people,dc=springframework,dc=org uniqueMember: uid=bob,ou=people,dc=springframework,dc=org dn: cn=managers,ou=groups,dc=springframework,dc=org objectclass: top objectclass: groupOfUniqueNames cn: managers ou: manager uniqueMember: uid=ben,ou=people,dc=springframework,dc=org uniqueMember: cn=mouse, jerry,ou=people,dc=springframework,dc=org dn: cn=submanagers,ou=subgroups,ou=groups,dc=springframework,dc=org objectclass: top objectclass: groupOfUniqueNames cn: submanagers ou: submanager uniqueMember: uid=ben,ou=people,dc=springframework,dc=org
在這里,我們突出顯示了一個(gè)用戶的數(shù)據(jù),我們將使用該數(shù)據(jù)來(lái)測(cè)試已實(shí)施的示例。
步驟3:更新 application.properties 文件
在此文件中,我們將擁有嵌入式 LDAP 的一些屬性,如下所示。
spring.ldap.embedded.port=8389 spring.ldap.embedded.ldif=classpath:ldap-data.ldif spring.ldap.embedded.base-dn=dc=springframework,dc=org
步驟4:創(chuàng)建一個(gè)用于基本身份驗(yàn)證的控制器類
下一步是創(chuàng)建一個(gè) RestController 類。
當(dāng)我們輸入憑據(jù)以登錄應(yīng)用程序時(shí),我們將看到一條成功登錄消息。讓我們創(chuàng)建一個(gè)簡(jiǎn)單的控制器 LoginController.java,如下所示。
@RestController public class LoginController { ? ? @GetMapping("/") ? ? public String getLoginPage() { ? ? ? ? return "登錄成功!"; ? ? } }?
步驟5:從 LdapSecurityConfig.java 創(chuàng)建一個(gè)配置類
這是我們將保留 LDAP 身份驗(yàn)證的整個(gè)邏輯的配置類,如下所示。
@Configuration public class LdapSecurityConfig extends WebSecurityConfigurerAdapter { ? ? @Override ? ? protected void configure(HttpSecurity http) throws Exception { ? ? ? ? ?http ? ? ? ? .authorizeRequests() ? ? ? ? .anyRequest().fullyAuthenticated() ? ? ? ? .and() ? ? ? ? .formLogin(); ? ? } ? ? @Override ? ? public void configure(AuthenticationManagerBuilder auth) throws Exception { ? ? ? ? ?auth ? ? ? ? .ldapAuthentication() ? ? ? ? .userDnPatterns("uid={0},ou=people") ? ? ? ? .groupSearchBase("ou=groups") ? ? ? ? .contextSource() ? ? ? ? .url("ldap://localhost:8389/dc=springframework,dc=org") ? ? ? ? .and() ? ? ? ? .passwordCompare() ? ? ? ? .passwordEncoder(new BCryptPasswordEncoder()) ? ? ? ? .passwordAttribute("userPassword"); ? ? } }?
注意:如果您使用 Spring Security 5.7.0-M2 或更高版本,不要使用 WebSecurityConfigurerAdapter。
5、如何測(cè)試應(yīng)用程序?
為了測(cè)試應(yīng)用程序,我們需要打開瀏覽器并點(diǎn)擊 URL http://localhost:8080/。
點(diǎn)擊 URL 后,將顯示默認(rèn)登錄頁(yè)面。此外,輸入 ldap-data.ldif 文件中給出的任何憑據(jù)。
如果輸入的憑據(jù)正確,您將看到使用 LDAP 身份驗(yàn)證成功登錄的消息。例如,讓我們觀察 ldap-data.ldif 文件中的以下用戶數(shù)據(jù)。
dn: uid=admin,ou=people,dc=springframework,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson cn: Admin sn: Admin uid: admin userPassword: $2a$10$ODZhWAyD0i8zruWQcMYx9ePkW2xXsqIljhh4K8spSOUCY897ERkwu
這里,aid是用戶名,userpassword是密碼的加密值。密碼的真實(shí)值為“admin@123”。
因此,我們需要提供 admin@123 作為密碼。單擊登錄按鈕后,您應(yīng)該在屏幕上看到消息“登錄成功!”。
我們可以使用下面的程序類來(lái)對(duì)任何密碼進(jìn)行編碼。
public class PasswordEncoder { ? ? public static void main(String[] args) { ? ? ? ? System.out.println(new BCryptPasswordEncoder().encode("admin@123")); ? ? } }?
6、總結(jié)
在本文中,我們涵蓋了“使用 Spring Boot 的 Spring Security LDAP 身份驗(yàn)證示例”的所有理論和示例部分。
最后,您應(yīng)該能夠?qū)崿F(xiàn) Spring Security LDAP 身份驗(yàn)證。同樣,您也可以根據(jù)自己的要求進(jìn)一步擴(kuò)展此示例。也嘗試在您的項(xiàng)目中相應(yīng)地實(shí)現(xiàn)它。
到此這篇關(guān)于Spring Security LDAP實(shí)現(xiàn)身份驗(yàn)證的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)Spring Security LDAP身份驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Eclipse發(fā)布到Tomcat丟失依賴jar包的問(wèn)題
這篇文章介紹了如何在Eclipse中配置部署裝配功能,以確保在將Web項(xiàng)目發(fā)布到Tomcat服務(wù)器時(shí)不會(huì)丟失任何依賴jar包,通過(guò)手動(dòng)配置或使用構(gòu)建工具腳本,可以自動(dòng)化這個(gè)過(guò)程,提高開發(fā)效率和應(yīng)用程序的穩(wěn)定性,感興趣的朋友跟隨小編一起看看吧2025-01-01在deepin上如何使用Fleet開發(fā)SpringBoot?3.0.0項(xiàng)目
這篇文章主要介紹了在deepin上使用Fleet開發(fā)SpringBoot?3.0.0項(xiàng)目的過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼
這篇文章主要介紹了SpringBoot使用Thymeleaf自定義標(biāo)簽的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09Java實(shí)現(xiàn)九九乘法表的完整實(shí)例(對(duì)齊版)
這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)九九乘法表(對(duì)齊版)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12基于Springboot疫苗接種行程管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
本文主要介紹了基于Springboot實(shí)現(xiàn)的疫苗接種行程管理系統(tǒng)的示例代碼,系統(tǒng)主要實(shí)現(xiàn)個(gè)人疫苗接種管理、行程管理、病史管理、風(fēng)險(xiǎn)地區(qū)管理、核酸檢測(cè)報(bào)告結(jié)果上報(bào)、疫情新聞管理等功能,需要的可以參考一下2022-03-03一文詳解SpringBoot中CommandLineRunner接口
Spring Boot的CommandLineRunner接口是一個(gè)函數(shù)式接口,用于在Spring Boot應(yīng)用程序啟動(dòng)后執(zhí)行一些初始化操作,它提供了一個(gè)run方法,該方法在應(yīng)用程序啟動(dòng)后被調(diào)用,本文給大家詳細(xì)介紹了SpringBoot中CommandLineRunner接口,需要的朋友可以參考下2023-10-10Java 基于AQS實(shí)現(xiàn)自定義同步器的示例
這篇文章主要介紹了Java 基于AQS實(shí)現(xiàn)自定義同步器的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-03-03HttpUtils 發(fā)送http請(qǐng)求工具類(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇HttpUtils 發(fā)送http請(qǐng)求工具類(實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07