概述
之前所有基于Spring Security 实现OAuth2的文章中,都将用户的身份认证过程简单化了。无论是假设账号密码直接存在MySQL数据库中,还是通过实现UserDetailsService
的接口,都需要保证一个前提:可以在身份管理库中,通过账号查询出对应的密码。
但是熟悉LDAP的人应该知道,我们是无法通过账号去获取密码的,因此是无法按照之前的方式实现用户身份认证的。基于LDAP的身份管理,Spring Security有另外一种方式实现身份认证,这就是本文要展现的。
环境准备
在做Spring Security集成LDAP的身份验证之前,我们要提前准备好 LDAP Server 的环境。
LDAP 的全称是 Lightweight Directory Access Protocol,「轻量目录访问协议」。LDAP 「是一个协议」,约定了 Client 与 Server 之间的信息交互格式、使用的端口号、认证方式等内容。而 「LDAP 协议的实现」,有着众多版本,例如:
- 微软的 Active Directory:是 LDAP 在 Windows 上的实现,AD 实现了 LDAP 所需的树形数据库、具体如何解析请求数据并到数据库查询然后返回结果等功能。
- OpenLDAP:是可以运行在 Linux 上的 LDAP 协议的开源实现。
而我们平常说的 LDAP Server,一般指的是安装并配置了 Active Directory、OpenLDAP 这些程序的服务器。
显然安装微软的AD是比较麻烦的,简单来弄的话,这里就基于docker来安装开源的OpenLDAP。因为spring-security-ldap
是和LDAP协议集成的,所以无论AD还是OpenLDAP都没差别。这里除了安装OpenLDAP,还安装管理前者的客户端phpLDAPadmin。
OpenLDAP安装脚本
#!/bin/bash
docker stop openldap
echo '容器已停止'
docker rm openldap
echo '容器已删除'
docker run -d \
--name openldap \
--restart=on-failure:3 \
-p 389:389 \
-p 636:636 \
--network bridge \
--hostname openldap-host \
--env LDAP_ORGANISATION="example" \
--env LDAP_DOMAIN="example.com" \
--env LDAP_ADMIN_PASSWORD="123456" \
osixia/openldap
echo '容器已启动'
phpLDAPadmin安装脚本
#!/bin/bash
docker stop phpldapadmin
echo '容器已停止'
docker rm phpldapadmin
echo '容器已删除'
docker run -d \
--name phpldapadmin \
--restart=on-failure:3 \
-p 8080:80 \
--link openldap \
--privileged \
--env PHPLDAPADMIN_HTTPS=false \
--env PHPLDAPADMIN_LDAP_HOSTS=openldap \
osixia/phpldapadmin
echo '容器已启动'
启动成功后,本地访问 http://localhost:8080 即进入phpLDAPadmin的管理页面。因为在OpenLDAP启动时设置了admin的秘密,因此在登录页面,输入账号/密码(cn=admin,dc=example,dc=com/123456)登录。
后续关于phpLDAPadmin上对象的创建和管理,可以自行查找资料,这里就不介绍了。
代码
基于之前oauth2-server的代码就行修改,主要是修改基于UserDetailsService
的接口实现身份认证的部分。
pom.xml
引入集成spring security 和 ldap 的依赖。
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
在配置文件中自定义创建ldap的一些连接数据,并通过@ConfigurationProperties
配置数据映射的类。
application.yml
custom:
ldap:
security:
search-base: cn=Users
search-filter: cn={0}
url: ldap://localhost:389/dc=example,dc=com
manage-dn: cn=admin,dc=example,dc=com
manage-password: 123456
LdapSecurityProperty.java
@Data
@ConfigurationProperties("custom.ldap.security")
public class LdapSecurityProperty {
private String searchBase;
private String searchFilter;
private String url;
private String manageDn;
private String managePassword;
}
用户的身份验证是在WebSecurityConfigurerAdapter
接口public void configure(AuthenticationManagerBuilder auth)
方法中实现的,因此只要修改该方法即可。我们在下列代码中对比这两种代码实现。
1、通过实现UserDetailsService做身份验证
// 依赖注入 userDetailsService
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setPasswordEncoder(new PasswordEncoderImpl());
authProvider.setUserDetailsService(userDetailsService);
auth.authenticationProvider(authProvider);
auth.inMemoryAuthentication();
}
2、通过集成LDAP做身份验证
// 依赖注入 ldapSecurityProperty
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.userSearchBase(ldapSecurityProperty.getSearchBase())
.userSearchFilter(ldapSecurityProperty.getSearchFilter())
.contextSource()
.url(ldapSecurityProperty.getUrl())
.managerDn(ldapSecurityProperty.getManageDn())
.managerPassword(ldapSecurityProperty.getManagePassword());
}
以上代码修改,就将Spring Security的用户账号、密码验证,集成到LDAP中管理了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。