【问题标题】:Spring Boot Security/LDAP direct bind with user credentialsSpring Boot Security/LDAP 直接绑定用户凭证
【发布时间】:2019-09-18 07:16:30
【问题描述】:

有没有办法通过 Spring Boot Security/LDAP 使用凭据来验证用户身份,而不是先绑定一些功能凭据,然后再尝试绑定用户?

我不想像这样使用managerDnmanagerPassword

auth.ldapAuthentication()
    .userSearchBase("")
    .userSearchFilter("(samAccountName={0})")
    .contextSource()
        .url("ldap://<url>/<root>")
        .managerDn("functionUser")
        .managerPassword("password")

【问题讨论】:

  • 如果您使用的 LDAP 服务器允许匿名访问,则不需要技术用户。

标签: spring-boot spring-security spring-ldap spring-security-ldap


【解决方案1】:

在我的应用程序中,我实现了一个自定义 UsernamePasswordAuthenticationProvider,根据用户记录中设置的标志,根据我自己的数据库或远程 LDAP 对用户进行身份验证。

为了针对远程 LDAP 进行身份验证,我使用了以下代码。它对我有用,也许它也对你有用:)。

protected void validateCredentialsAgainstActiveDirectory(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) {
    try {
        LdapConfiguration config  = ...;
        
        /*
         * We will create a new LDAP connection on the fly each time an AD user logs in.
         * Hence we must disable caching properties to avoid NullPointerException later
         * in AbstractContextSource.getAuthenticatedEnv().
         * 
         */
        DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource(config.getUrl());
        contextSource.setCacheEnvironmentProperties(false);
        
        // Authenticate the user against the pre-configured userDnTemplate
        BindAuthenticator bindAuthenticator = new BindAuthenticator(contextSource);
        bindAuthenticator.setUserDnPatterns(new String[] { config.getUserDnTemplate() });
        bindAuthenticator.authenticate(authentication);
    
    } catch (BadCredentialsException ex) {
        // Catch downstream exception to return our own message
        throw new BadCredentialsException(SpringUtils.getMessage("security.login.error.bad-credentials"));
        
    }
}

仅供参考,LdapConfiguration 是我自己的自定义类,用于从 .yml 文件中读取配置。在这个文件中,我配置了 LDAP 服务器的 url 和 DN 模板,如下所示。你需要改变它以适应你的环境。

url: ldap://10.10.10.231:10389/dc=mycompany,dc=com
userDnTemplate: uid={0},ou=people

不要忘记在您的项目中也导入必要的依赖项。

<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-ldap</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.ldap</groupId>
  <artifactId>spring-ldap-core</artifactId>
</dependency>

【讨论】:

  • 构建 DN 实际上不是最佳实践,因为这不允许拥有任意目录信息树 (DIT)。最佳做法是通过 SEARCH 操作检索连续 BIND 操作的条目 DN。
  • @BernhardThalmayr 我模仿了 Spring LDAP Authentication Provider 的实现:)。我没有足够的 LDAP 经验来评估当前的工作解决方案是否是最好的解决方案,但它确实有效。您介意提供答案并向我们展示使用 SEARCH 操作的更好方法吗?对此我将不胜感激。
  • 只要你的 DIT 真的很简单,它就可以工作,这里所有的“用户”条目都在条目“ou=people,dc=mycompany,dc=com”下面……在真实的企业中,这是很少出现这种情况,因为应该验证的“用户”条目分布在不同的容器中。因此,您使用唯一属性进行搜索 - 在 AD 中,这通常是“samAccountName”,但您可以使用任何保证唯一的属性。并非每个 LDAP 目录服务器都允许使用空 DN "" 作为搜索库,因此搜索库必须由 LDAP 管理员提供。
  • 非常智能的 LDAP 客户端正在查询所谓的“rootDSE”,以了解它们正在与之通信的 LDAP 服务器的功能。
猜你喜欢
  • 2016-12-18
  • 2013-12-28
  • 2015-11-22
  • 2012-09-04
  • 2016-08-11
  • 2021-11-10
  • 2017-11-02
  • 1970-01-01
  • 2011-08-18
相关资源
最近更新 更多