SSO Server 认证数据源-LDAP

189 阅读1分钟

Single Sign-On Server LDAP数据库集成

上一篇文章中,我将MySQL数据库引入到了CAS服务器中,然而在企业内部应用中,员工信息通常存储在LDAP数据库,因此这篇文章将介绍如何集成LDAP数据库进行用户认证。

1.引入依赖

首先导入LDAP数据库的依赖:

        <!--ldap-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-ldap</artifactId>
        </dependency>

2.认证实现

上一篇文章中,我们定义了AuthenticationProvider接口,并搭好了整体框架,并写了一个MySQL的实现类,这一次实现LDAP的即可,扩展非常容易。


/**
 * @author hundanli
 * @version 1.0.0
 * @date 2024/3/27 14:52
 */
@Slf4j
@Service
public class LdapAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private LdapTemplate ldapTemplate;

    private final String[] attributesToReturn = {
            "sAMAccountName",
            "mail",
            "mobile",
            "name",
            "employeeId",
            "distinguishedName"
    };
    private static final String OBJECT_CLASS_KEY = "objectClass";
    private static final String SAM_ACCOUNT_NAME_KEY = "sAMAccountName";


    @Override
    public Authentication authenticate(Authentication authentication) {
        String accountName = authentication.getPrincipal();
        String password = authentication.getCredential();
        LdapPerson ldapPerson = authenticateUser(accountName, password);
        if (ldapPerson != null && ldapPerson.getDistinguishedName() != null) {
            ldapPerson = searchPerson(accountName);
            authentication.setAuthenticated(true);
            authentication.setAttributes(collectAttributes(ldapPerson));
        }
        return authentication;
    }

    @Override
    public boolean supports(AuthenticationType authenticationType) {
        return AuthenticationType.PASSWORD.equals(authenticationType);
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }


    private LdapPerson searchPerson(String accountName) {
        return ldapTemplate.searchForObject(
                query().attributes(attributesToReturn)
                        .where(SAM_ACCOUNT_NAME_KEY).is(accountName),
                new PersonContextMapper());
    }


    private LdapPerson authenticateUser(String accountName, String password) {
        // 使用LDAP校验用户名和密码是否正确
        ContainerCriteria criteria = query()
                .where(SAM_ACCOUNT_NAME_KEY).is(accountName);
        return ldapTemplate.authenticate(criteria, password, new AuthenticatedContextMapper());
    }

    private Map<String, Object> collectAttributes(LdapPerson ldapPerson) {
        Map<String, Object> attributes = new HashMap<>(8);
        attributes.put(AttributeNames.SAM_ACCOUNT_NAME, ldapPerson.getSAMAccountName());
        attributes.put(AttributeNames.NAME, ldapPerson.getName());
        attributes.put(AttributeNames.EMPLOYEE_ID, ldapPerson.getEmployeeId());
        attributes.put(AttributeNames.MAIL, ldapPerson.getMail());
        attributes.put(AttributeNames.MOBILE, ldapPerson.getMobile());
        return attributes;
    }

}

相关的其他功能类比较简单,不再细说。

3.数据源配置

在application.properties文件中,添加LDAP数据库信息:

spring.ldap.username=username
spring.ldap.password=password
spring.ldap.urls=ldap://10.120.99.5:389
spring.ldap.base=DC=hundanli,DC=com

完整代码:github.com/hundanLi/ha…