配置 Spring Security 以在没有匿名和没有绑定 DN 的情况下针对 LDAP 进行身份验证

Posted

技术标签:

【中文标题】配置 Spring Security 以在没有匿名和没有绑定 DN 的情况下针对 LDAP 进行身份验证【英文标题】:Configuring Spring Security to Authenticate against LDAP without anonymous and without bind DN 【发布时间】:2016-04-12 09:57:21 【问题描述】:

使用 JNDI,我可以成功地对我们的 LDAP 服务器进行身份验证,该服务器已禁用匿名绑定,仅使用用户的用户名和密码,如下所示:

    Hashtable<String, Object> env = new Hashtable<String, Object>();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, url);

    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, userName);
    env.put(Context.SECURITY_CREDENTIALS, password);
    DirContext ctx = new InitialDirContext(env);
    Attribute groups = ctx.getAttributes(userName).get("groupMembership");

现在我想使用 Spring Boot、Spring Security 和 Spring LDAP 做同样的事情。

我可以使用绑定 DN 和密码成功配置身份验证,如下所示:

    DefaultSpringSecurityContextSource context = new DefaultSpringSecurityContextSource(ldapConfig.url);
    context.setUserDn(ldapConfig.bindDn);
    String bindPassword = passwordResolver.getPassword(ldapConfig.password);
    context.setPassword(bindPassword);
    context.afterPropertiesSet();

    CustomAuthoritiesPopulator customAuthoritiesPopulator = new CustomAuthoritiesPopulator(context, ldapConfig.groupSearchBase);

    String[] dnPatArr = new String[ldapConfig.userDnPatterns.size()];
    ldapConfig.userDnPatterns.toArray(dnPatArr);

    auth.ldapAuthentication()
        .ldapAuthoritiesPopulator(customAuthoritiesPopulator)
        .contextSource(context)
        .userDnPatterns(dnPatArr)
        .groupSearchBase(ldapConfig.groupSearchBase);

这行得通——Spring Boot webapp 将成功验证我的用户。

但我想在不传递绑定 DN 和绑定密码的情况下执行此操作,就像我对 JNDI 示例所做的那样。

如果我只是省略设置绑定 DN 和密码,我会得到“LDAP:错误代码 48 - 匿名简单绑定已禁用。”。

我不想进行匿名绑定——我希望 Spring 使用用户提供的用户名和密码来对我的每个绑定 DN 模式进行简单的绑定,直到其中一个有效为止。

我已阅读文档,但我很难确定这是否可行。 JNDI 可以做到这一点,所以我认为我应该能够让 Spring 做到这一点。我考虑过编写自己的自定义 Spring Security 身份验证提供程序,但肯定没有必要。

【问题讨论】:

【参考方案1】:

在 JNDI 中,身份验证信息在环境属性中指定。请确保属性名称拼写正确。

例如,凭据的环境属性是 java.naming.security.credentials 而不是 java.naming.security.credential。注意最后的missing letter 's' 会给出

“LDAP:错误代码 48 - 匿名简单绑定已禁用。”

<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">      
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</prop>
            <prop key="java.naming.provider.url">ldap://serverURL/jndi_ctx
            </prop>
            <prop key="java.naming.security.authentication">simple</prop>
            <prop key="java.naming.security.principal">user_id</prop>
            <prop key="java.naming.security.credentials">password</prop>            
        </props>
    </property>
</bean>

【讨论】:

以上是关于配置 Spring Security 以在没有匿名和没有绑定 DN 的情况下针对 LDAP 进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

配置 Spring Security 以在认证后返回 JSON 响应

Spring Security(11)——匿名认证

Spring Security(11)——匿名认证

Spring Security - 访问被拒绝(用户不是匿名的)spring-security-core-4.0.3.RELEASE

匿名用户的 Spring Security 和 RequestCache

Spring Security 入门(1-11)Spring Security - 匿名认证