栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot 集成 LDAP获取用户信息

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot 集成 LDAP获取用户信息

测试环境:
SpringBoot: 2.4.0
Window Server: 2012R2
Ldap browser: Softerra LDAP Administrator 2021.1 (32-bit)
附带 Spring LDAP 文档 官网文档

1. 新建一个 SpringBoot 项目

添加 LDAP 依赖包


    org.springframework.boot
    spring-boot-starter-data-ldap

2. 配置 LDAP 连接

在 application.yml中配置
注意下面对应的 dc 等信息均以 a,b 字符代替,使用时替换成项目的地址即可

spring:
  ldap:
    urls: ldap://a.b.com:389
    username: c@b.com
    password: xxxxxxxxx
    base: dc=b,dc=com
3. 添加数据接口 3.1 创建 AD 用户实例类
@Data
@Entry(base = "dc=b,dc=com", objectClasses = "user")
public class Person {

    @Id
    private Name id;
    @Attribute(name = "cn")
    private String cn;
    @Attribute(name = "sn")
    private String sn;
    @Attribute(name="mail")
    private String mail;
    @Attribute(name="telephoneNumber")
    private String telephoneNumber;
    @Attribute(name="description")
    private String description;
    @Attribute(name="givenName")
    private String givenName;

}
3.2 创建一个 PersonReposity 数据接口
public interface PersonRepository extends LdapRepository {}
3.3 测试接口

下面测试获取用户、验证接口

  1. 获取所有用户信息
personRepository.findAll().forEach(System.out::pringln)

打印结果(这里屏蔽了部分敏感信息就不展示了)

Person(id=CN=Administrator,CN=Users, cn=Administrator, sn=null, mail=null, telephoneNumber=null, description=***, givenName=null)
Person(id=CN=Guest,CN=Users, cn=Guest, sn=null, mail=null, telephoneNumber=null, description=****, givenName=null)
Person(id=CN=***,CN=Users, cn=Alan, sn=null, mail=null, telephoneNumber=null, description=null, givenName=null)
Person(id=CN=***,OU=Domain Controllers, cn=***, sn=null, mail=null, telephoneNumber=null, description=null, givenName=null)
Person(id=CN=***,CN=Users, cn=krbtgt, sn=null, mail=null, telephoneNumber=null, description=***, givenName=null)
Person(id=CN=***,CN=Users, cn=huangalan, sn=huang, mail=null, telephoneNumber=null, description=null, givenName=alan)
Person(id=CN=a,CN=Users, cn=a, sn=a, mail=test@123.com, telephoneNumber=123123123123123, description=teststsetsetsetsetsetset, givenName=a-name)
  1. 获取单个用户信息
    以上面的 cn=a用户为例
personRepository.findOne(query().where("cn").is("a"), Person.class);

打印结果:

Person(id=CN=a,CN=Users, cn=a, sn=a, mail=test@123.com, telephoneNumber=123123123123123, description=teststsetsetsetsetsetset, givenName=a-name)
  1. 验证用户账户
    这里以 cn=a为例,传入用户名和密码测试
String password = "123456";
String username = "a";
personRepository.authenticate(query().where("cn").is(username ), password ,
                (dirContext, ldapEntryIdentification) ->
                        ldapTemplate.findOne(query().where(attribute).is(username), Person.class));

打印结果:

Person(id=CN=a,CN=Users, cn=a, sn=a, mail=test@123.com, telephoneNumber=123123123123123, description=teststsetsetsetsetsetset, givenName=a-name)

LdapRepository 已经封装了很多操作用户接口,这里就不一一测试了,有兴趣的童鞋可以自己测试,诸如:

delete()
deleteAll()
findById()
existById()
....
直接调用即可
4. 整合封装

将上面接口整合成一个 service

public interface LdapService {

    
    Iterable findAllPersons();

    
    Person findOnePerson(String attribute, String value);

    
    Person authenticate(String attribute, String username, String password);

}
@Service
@Slf4j
public class LdapServiceImpl implements LdapService {

    private final LdapTemplate ldapTemplate;
    private final PersonRepository personRepository;

    @Autowired
    public LdapServiceImpl(LdapTemplate ldapTemplate, PersonRepository personRepository) {
        this.ldapTemplate = ldapTemplate;
        this.personRepository = personRepository;
    }

    @Override
    public Iterable findAllPersons() {
        return personRepository.findAll();
    }

    @Override
    public Person findOnePerson(String attribute, String value) {
        try {
            return ldapTemplate.findOne(query().where(attribute).is(value), Person.class);
        } catch (EmptyResultDataAccessException e) {
            log.error("Found 0 result, error: {}", e.getMessage());
        }
        return null;
    }

    @Override
    public Person authenticate(String attribute, String username, String password) {
        return ldapTemplate.authenticate(
                query().where(attribute).is(username),
                password,
                (dirContext, ldapEntryIdentification) ->
                        ldapTemplate.findOne(query().where(attribute).is(username), Person.class));
    }
}

整合完毕 !!

5. 可能遇到的问题

PartialResultException: Unprocessed Continuation Reference(s); remaining name '/'
这个是 AD 无法进行自动处理引用的原因,解决方法:忽略这个异常,设置 setIgnorePartialResultException 为 true

@Autowired
private final LdapTemplate ldapTemplate;
......
ldapTemplate.setIgnorePartialResultException(true);

AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903C5, comment: AcceptSecurityContext error, data 52e, v2580
这个错误一般是上面第二步配置 yml 的 username 不正确造成

spring:
  ldap:
    urls: ldap://a.b.com:389
    ## 这里出错
    username: c@b.com
    password: xxxxxxxxx
    base: dc=b,dc=com

解决方法:
username 配置方式推荐这两种

  1. 属性配置形式:CN=a,CN=Users,DC=b,DC=com
  2. 域名形式: a@b.com a 为登陆用户名,b.com 是上面配置的 dc=b,dc=com 组合

推荐 LDAP browser :Softerra LDAP Administrat, 官网下载地址

附带简单教程
安装的话直接一路 next 即可,中间可配置安装路径
安装完成后打开软件连接 LDAP

  1. 新建一个 Profile

    输入连接名称,随便输即可
  2. 连接参数配置

    Host 是 AD 域的连接地址,例如域 ADtest 和 IP 地址都可以,端口默认 389
    base dn 这些信息可以从AD ACSI管理器查看,然后点击下一步

    这里是输入连接凭证的,Principal Password 输入 yml 中配置的 username 和 password 点击下一步即可,等待验证链接完成就可以查看所有用的信息啦
6. 完结撒花

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/340100.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号