首页 > 解决方案 > Spring LDAP 身份验证问题

问题描述

所以这是我第一次使用 Spring,所以请多多包涵!

我很确定问题在于我对 DnPatterns 和组搜索库的设置不正确。

我正在尝试连接一个外部广告。使用广告资源管理器我找到了一个条目,下面是用户的 dn,然后是他们通常用来登录的登录 id

在 AD Explorer 视图中的用户配置文件中收听

DN -> CN=LastName\, FirstName, OU=Users,OU=Calgary,DC=CORP,DC=DEPARTMENT,DC=com

用户名和密码用户将在登录时提供:

UserName ->  LastFirst5
Password ->  Password

在目录资源管理器中到达用户信息的路径如图所示

DC=CORP,DC=DEPARTMENT,DC=com -> OU=Calgary -> OU=Users -> CN=LastName,FirstName

这是我的配置设置:

    @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("DC=corp,DC=department,DC=com")
                .groupSearchBase("OU=Users,OU=Calgary,DC=CORP,DC=Department,DC=com")
                .contextSource()
                .url("ldap://corp.Ad.com/")
                .and()
                .passwordCompare()
                .passwordEncoder(new LdapShaPasswordEncoder())
                .passwordAttribute("userPassword");
    }

标签: javaspring-bootauthenticationldap

解决方案


  • 首先,上下文源 url 应该包括用于搜索和/或验证用户的基本 DN。

    .contextSource()
      .url('ldap://corp.Ad.com:389/DC=CORP,DC=DEPARTMENT,DC=com')
    
  • userDnPatterns()用于匹配出现在用户条目的 RDN 中的用户登录名 -如果出现!- 然后服务器将用户输入的登录名替换为 {0} 占位符,然后通过附加 LDAP url 中的基本 dn 重新创建用户 dn。问题在于,在您的目录中,用户 dn不是根据其用户名构建的,而是根据其cn不同的属性构建的,因此您无法匹配(LastName, FirstName ≠ LastFirst5),因此您无法使用此方法对用户进行身份验证(但使用正确的模式看起来cn={0},ou=Users如果用户名和 cn 是等价的)。

  • userSearchFilter()另一方面,可用于匹配用户使用常规搜索过滤器提供的登录名。userSearchBase()可以选择使用它来设置一个可选的分支 rdn,用户条目所在的位置以及执行搜索的位置,如果未指定,则搜索包括从 LDAP url 的基本 dn 开始的整个目录。

    .and()
      .userSearchBase('ou=Users,ou=Calgary')
      .userSearchFilter('(sAMAccountName={0})')
    

    请注意,如果您在其他城市有用户,例如OU=Users,OU=OtherCity,DC=...,您将需要其他配置才能在不知道从哪个城市开始搜索的情况下对他们进行身份验证。在这种情况下,您将重置搜索库以匹配基本 dn 下的所有条目,并且由于您只希望用户能够登录,因此您将相应地优化过滤器:

    .and()
      .userSearchBase('')
      .userSearchFilter('(&(sAMAccountName={0})(objectClass=user)')
    
  • 您不需要groupSearchBase()没有groupSearchFilter(),这两个仅用于授权(验证用户具有给定角色 <=> 是给定组的成员)。

  • 为了能够搜索和匹配用户条目,身份验证请求本身需要连接并绑定到 LDAP 服务器,大多数服务器不接受匿名绑定,因此您可能需要设置 managerDn() 和 managerPassword() :

    .contextSource()
      .url('ldap://corp.Ad.com:389/DC=CORP,DC=DEPARTMENT,DC=com')
      .managerDn('admin')
      .managerPassword('password')
    

https://community.jaspersoft.com/documentation/jasperreports-server-authentication-cookbook/performing-ldap-user-search


推荐阅读