【问题标题】:Authentication with Spring-Security via Active Directory LDAP通过 Active Directory LDAP 使用 Spring-Security 进行身份验证
【发布时间】:2020-02-16 06:02:35
【问题描述】:

我无法使用真实的活动目录进行身份验证,让我更好地解释一下我尝试使用 spring.io 提出的示例进行身份验证,没有问题,内部服务启动没有任何问题。 参考https://spring.io/guides/gs/authenticating-ldap/

我尝试通过插入我的活动目录的配置来修改下面的代码,但没有成功。您能否指导我或向我展示一个真实的案例,即在不使用示例中的内部服务的情况下建立真正的连接?我上网查了一下,发现都和官方的例子差不多,没有任何真实案例

@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 LdapShaPasswordEncoder())
                    .passwordAttribute("userPassword");
    }

错误显示: LDAP 处理期间发生未分类异常;嵌套异常为 javax.naming.NamingException: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C0907C2,注释:为了执行此操作,必须在连接上成功绑定。,数据 0,v2580

【问题讨论】:

  • 基于 LDAP 的做法是搜索 EntryDN,然后使用找到的 DN 和提供的密码执行身份验证。很奇怪,该指南显示使用 DN 合作伙伴作为首选。只有在极少数情况下,目录信息树才会是“平面”树。密码比较也是不好的做法。
  • 通常也不允许匿名访问生产目录服务器,因此您需要一个“服务帐户”(特殊的 Bind-DN),可用于对目录服务器执行 LDAP 操作。跨度>

标签: spring spring-security active-directory ldap spring-ldap


【解决方案1】:

我在这里找到了一个样本,这很有用:

https://github.com/sachin-awati/Mojito/tree/master/webapp/src/main/java/com/box/l10n/mojito/security

如果在 Active Directory 查找期间未找到用户 - loadUserByUsername,您可以选择实现UserDetailsContextMapperImpl,它会覆盖mapUserFromContext 以创建UserDetails 对象。

@Component
public class UserDetailsContextMapperImpl implements UserDetailsContextMapper {

    @Override
    public UserDetails mapUserFromContext(DirContextOperations dirContextOperations, String username, Collection<? extends GrantedAuthority> authorities) {

        UserDetails userDetails = null;

        try {
            userDetails = userDetailsServiceImpl.loadUserByUsername(username);

        } catch (UsernameNotFoundException e) {
            String givenName = dirContextOperations.getStringAttribute("givenname");
            String surname = dirContextOperations.getStringAttribute("sn");
            String commonName = dirContextOperations.getStringAttribute("cn");

            userDetails = userDetailsServiceImpl.createBasicUser(username, givenName, surname, commonName);
        }

        return userDetails;
    }

确保您使用的是ActiveDirectoryLdapAuthenticationProvider spring 安全类,因为与其他 LDAP 服务器相比,Active Directory 有自己的细微差别。您可能需要在安全配置类中使用 @EnableGlobalAuthentication 注释,因为您可以有多个 AuthenticationManagerBuilders,这会造成很多混乱。

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        ActiveDirectoryLdapAuthenticationProvider adProvider =
                new ActiveDirectoryLdapAuthenticationProvider("domain.com", "ldap://primarydc.domain.com:389");
        adProvider.setConvertSubErrorCodesToExceptions(true);
        adProvider.setUseAuthenticationRequestCredentials(true);
        auth.authenticationProvider(adProvider);
}

更多细节在这里: https://github.com/spring-projects/spring-security/issues/4324 https://github.com/spring-projects/spring-security/issues/4571

【讨论】:

    【解决方案2】:

    是的,通过 LDAP 进行身份验证太痛苦了。为了能够对 AD 执行身份验证,您需要使用 ActiveDirectoryLdapAuthenticationProvider。 这是工作示例:

    @Override
    protected void configure(AuthenticationManagerBuilder auth) {
        ActiveDirectoryLdapAuthenticationProvider adProvider =
                new ActiveDirectoryLdapAuthenticationProvider("domain.com", "ldap://localhost:8389");
        adProvider.setConvertSubErrorCodesToExceptions(true);
        adProvider.setUseAuthenticationRequestCredentials(true);
        auth.authenticationProvider(adProvider);
    }
    

    为了节省您的时间,请阅读以下内容,这非常重要: AD authentication doc

    【讨论】:

      猜你喜欢
      • 2014-12-01
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      • 2011-01-12
      • 2010-09-15
      • 2014-06-11
      相关资源
      最近更新 更多