【问题标题】:Authentication using LDAP against ADAM using spring security使用 Spring Security 对 ADAM 使用 LDAP 进行身份验证
【发布时间】:2011-04-16 20:58:17
【问题描述】:

我正在尝试使用 spring-security 让 Java 应用程序与我设置的本地 ADAM 实例通信。

我已经成功安装了ADAM,设置如下......

  • 在 localhost:389 上运行的实例
  • 根是O=Company
    • 一个叫OU=Company Users(组织单位)的孩子
      • 一个叫CN=Mike Q(用户)的孙子
      • uid = mikepassword = welcome

然后我设置了 spring-security(版本 3.0.3、spring-framework 3.0.4 和 spring-ldap 1.3.0)。弹簧文件

  <security:ldap-server id="contextSource" url="ldap://localhost:389/o=Company"/>

  <security:authentication-manager>
    <security:ldap-authentication-provider user-dn-pattern="uid={0},ou=Company Users"/>
  </security:authentication-manager>

  <bean class="com.xxx.test.TestAuthentication" lazy-init="false"/>

和TestAuthentication

public class TestAuthentication
{
    @Autowired
    private AuthenticationManager authenticationManager;

    public void initialise()
    {
        Authentication authentication = new UsernamePasswordAuthenticationToken( "mike", "welcome" );
        Authentication reponseAuthentication = authenticationManager.authenticate( authentication );
    }
}

运行这个我得到以下错误

Caused by: javax.naming.AuthenticationException: [LDAP: error code 49 - 8009030C: LdapErr: DSID-0C090336, comment: AcceptSecurityContext error, data 2030, vece]
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3041)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2987)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2789)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2703)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:293)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:175)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:193)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:136)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:66)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:667)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288)
at javax.naming.InitialContext.init(InitialContext.java:223)
at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:134)
at org.springframework.ldap.core.support.LdapContextSource.getDirContextInstance(LdapContextSource.java:43)
at org.springframework.ldap.core.support.AbstractContextSource.createContext(AbstractContextSource.java:254)

如果有人能指出我哪里出错了,我将不胜感激。此时我只想使用 LDAP 验证输入的用户/密码,没有比这更复杂的了。

我也对一些一般性观点感兴趣,因为这是我第一次涉足 LDAP 世界。

  • LDAP 区分大小写吗?
  • 最好避免空格吗?
  • 避免在 LDAP 查询中以明文形式发送密码的一般用例/最佳做法是什么?

【问题讨论】:

    标签: java authentication spring-security adam


    【解决方案1】:

    好的,因为我花了很多时间来解决这个问题。

    错误码2030表示用户的DN无效。

    经过一些试验和错误,这里是一个可以正常工作并且用户搜索正确的配置。 (您可能可以使用安全命名空间重写它,但是当我在处理这个时,使用原始 bean 定义会更清楚)。

      <bean id="contextSource"
            class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
        <constructor-arg value="ldap://localhost:389/cn=Sandbox,dc=ITOrg"/>
        <property name="userDn" value="cn=superuser,cn=People,cn=Sandbox,dc=ITOrg"/>
        <property name="password" value="xxxxxx"/>
      </bean>
    
      <bean id="ldapAuthProvider"
            class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
        <constructor-arg>
          <bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
            <constructor-arg ref="contextSource"/>
            <property name="userDnPatterns">
              <list>
                <value>cn={0},cn=People</value>
              </list>
            </property>
          </bean>
        </constructor-arg>
      </bean>
    
      <bean id="userSearch" class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
        <constructor-arg index="0" value="cn=People"/>
        <constructor-arg index="1" value="(cn={0})"/>
        <constructor-arg index="2" ref="contextSource"/>
      </bean>
    

    关键是

    <property name="userDn" value="cn=superuser,cn=People,cn=Sandbox,dc=ITOrg"/>
    

    在上下文源中指定 userDn 时,它必须是完整的 DN(它不只是将它附加到 URL 中提供的基础(构造函数 arg)中。

    使用 BindAuthentication 时

    <value>cn={0},cn=People</value>
    

    此值是上下文源的 baseDn 之上的后缀。

    配置用户搜索时

        <constructor-arg index="0" value="cn=People"/>
        <constructor-arg index="1" value="(cn={0})"/>
    

    我无法让它与 cn=People 在第二个参数中一起工作,但这似乎工作正常。请注意,您可以使用用户的属性,例如(uid={0})

    下面是一些使用 bean 定义的示例代码...

        @Autowired
        private LdapUserSearch ldapUserSearch;
    
        @Autowired
        private AuthenticationProvider authenticationProvider;
    
        public void initialise()
        {
            DirContextOperations dirContextOperations = ldapUserSearch.searchForUser( "username" );
    
            Authentication authentication = authenticationProvider.authenticate( new UsernamePasswordAuthenticationToken( "username", "password" ) );    
        }
    

    其他一些随机花絮...

    Error 52b - Invalid password
    
    
    [LDAP: error code 32 - 0000208D: NameErr: DSID-031521D2, problem 2001 (NO_OBJECT), data 0, best match of: 'CN=Sandbox,DC=ITOrg'
         - This means the user is not in the administrator role (probably)
    

    希望这一切对其他人有所帮助。

    【讨论】:

      【解决方案2】:

      我通过将您尝试使用的用户添加为同一基本 DN 中的管理员角色成员来解决此问题。 希望有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-09
        • 2015-11-22
        • 2012-11-18
        • 2013-03-06
        • 2011-08-21
        • 2016-09-09
        • 2021-09-02
        • 2020-02-16
        相关资源
        最近更新 更多