Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用SpringLDAP对Active Directory进行身份验证的FastBind_Java_Spring_Authentication_Active Directory_Ldap - Fatal编程技术网

Java 使用SpringLDAP对Active Directory进行身份验证的FastBind

Java 使用SpringLDAP对Active Directory进行身份验证的FastBind,java,spring,authentication,active-directory,ldap,Java,Spring,Authentication,Active Directory,Ldap,我有一个SpringMVC应用程序(使用3.0.5版本),需要使用SpringLDAP绑定到Active Directory,以便简单且仅验证用户的凭据。该应用程序托管在Linux服务器上,因此我需要一个跨平台的解决方案。并且应用程序不使用Spring安全性 在此设置中实现用户身份验证的有效方法是什么?Active Directory支持FastBind控件(id=1.2.840.113556.1.4.1781),因此我想利用它,因为我只需要验证输入凭据,不需要从AD返回其他信息 谢谢 更新(7

我有一个SpringMVC应用程序(使用3.0.5版本),需要使用SpringLDAP绑定到Active Directory,以便简单且仅验证用户的凭据。该应用程序托管在Linux服务器上,因此我需要一个跨平台的解决方案。并且应用程序不使用Spring安全性

在此设置中实现用户身份验证的有效方法是什么?Active Directory支持
FastBind
控件(id=
1.2.840.113556.1.4.1781
),因此我想利用它,因为我只需要验证输入凭据,不需要从AD返回其他信息

谢谢

更新(7/16/2012):我将继续更新我的问题和决议的细节

根据@ig0774的回答,我编写了以下
连接控制
类:

package com.company.authentication;

import javax.naming.ldap.Control;

public class FastBindConnectionControl implements Control {

    @Override
    public String getID() {
        return "1.2.840.113556.1.4.1781";
    }

    @Override
    public boolean isCritical() {
        return true;
    }

    @Override
    public byte[] getEncodedValue() {
        return null;
    }
}
然后,我使用
FastBind
连接控制类扩展了
AbstractContextSource

package com.company.authentication;

import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.Control;
import javax.naming.ldap.InitialLdapContext;
import org.springframework.ldap.core.support.AbstractContextSource;

public class FastBindActiveDirectoryContextSource extends AbstractContextSource {

    @Override
    protected DirContext getDirContextInstance(Hashtable env) throws NamingException {
        return new InitialLdapContext(env, new Control[] { new FastBindConnectionControl() });
    }
}
最后,一个封装身份验证机制的服务类:

package com.company.authentication;

import javax.naming.AuthenticationException;
import javax.naming.directory.DirContext;
import org.springframework.ldap.core.ContextSource;
import org.springframework.ldap.support.LdapUtils;

public class ActiveDirectoryAuthService implements IAuthenticate {

    private ContextSource contextSource;
    public void setContextSource(ContextSource contextSource) {
        this.contextSource = contextSource;
    }

    @Override
    public boolean authenticate(final String login, String password) {
        try {
            DirContext ctx = contextSource.getContext(login, password);
            LdapUtils.closeContext(ctx);
            return true;
        }
        catch (Exception e) {
            return false;
        }
    }
}
在我的Spring应用程序上下文配置文件中,我添加了以下内容:

<bean id="ADContextSource" class="com.company.authentication.FastBindActiveDirectoryContextSource">
    <property name="url" value="ldaps://x.x.x.x:636" />
</bean>

<bean id="userAuthenticationService" class="com.company.authentication.ActiveDirectoryAuthService">
    <property name="contextSource" ref="ADContextSource" />
</bean>

由于
FastBind
仅“检查用户的凭据”,不执行组确定,因此最好使用可分辨名称和凭据将绑定请求发送到服务器。任何简单的绑定请求都应该通过安全连接传输。结果代码为
0
(零)的响应表示:

  • 服务器正在侦听和响应
  • 可分辨名称存在,并且凭据与存储在服务器数据库中的凭据匹配
  • LDAP客户端具有足够的访问权限来验证服务器上的会话

  • 是与目录服务器交互的最佳Java实现

    由于
    快速绑定
    仅“检查用户的凭据”,不执行组确定,因此最好只使用可分辨名称和凭据向服务器发送绑定请求。任何简单的绑定请求都应该通过安全连接传输。结果代码为
    0
    (零)的响应表示:

  • 服务器正在侦听和响应
  • 可分辨名称存在,并且凭据与存储在服务器数据库中的凭据匹配
  • LDAP客户端具有足够的访问权限来验证服务器上的会话

  • 是与目录服务器交互的最佳Java实现

    在JNDI中实现
    FastBind
    控件是非常直接的

    基本上,您可以为
    FastBind
    控件创建一个新的
    Control
    类:

    class FastBindConnectionControl implements Control {
        public byte[] getEncodedValue() {
                return null;
        }
        public String getID() {
            return "1.2.840.113556.1.4.1781";
        }
        public boolean isCritical() {
            return true;
        }
    }
    
    然后使用它来创建ldap上下文(错误处理和忽略所有其他内容):

    理想情况下,这将很容易插入SpringLDAP,SpringLDAP是用于LDAP的JNDIAPI的包装器;但是,内置接口似乎不接受处理连接控件的参数,因此您显然需要创建自己的子类来处理该问题,这看起来应该足够简单:

    class FastBindLdapContextSource extends AbstractContextSource {
        protected DirContext getDirContextInstance(Hashtable env) {
            return new InitialLdapContext(env, new Control[] {new FastBindConnectionControl()});
        }
    }
    
    然后,您只需要将当前的
    LdapContextSource
    替换为
    FastBindLdapContextSource
    的实例

    但是,请注意,此上下文源只能用于
    BIND
    操作。正如我在给特里·加德纳的评论中提到的:

    在此模式下,连接上只接受简单绑定。因为没有进行组计算,所以连接的处理总是如同所有其他LDAP操作都没有发生绑定一样

    这意味着您可能需要维护两种类型的LDAP上下文,一种用于绑定,另一种用于实际执行您可能需要执行的任何查找


    查看,我看到
    authenticate
    方法看起来不仅仅是一个简单的绑定。更具体地说,它搜索用户,然后尝试绑定。因为,如果使用启用了
    FastBind
    的上下文,则不太可能执行搜索(通常AD不允许对匿名连接进行搜索)。基本上,这意味着您可能必须避免使用
    LdapTemplate

    然而,假设您获得了对AdContextSourcebean的引用,它应该足够简单,可以执行以下操作

    boolean authenticate(String username, String password) {
        try {
            DirContext ctx = contextSource.getContext(username, password);
            LdapUtils.closeContext(ctx);
            return true;
        } catch (Exception e) {
            // note: this means an exception was thrown by #getContext() above
            return false;
        }
    }
    

    它非常接近于
    LdapTemplate
    将要做的事情(唯一缺少的是
    AuthenticatedLdapEntryContextCallback
    ,它在本场景中没有任何价值,以及
    AuthenticationErrorCallback
    ,如果您想要这种行为,可以很容易地添加到其中)如前所述,在JNDI中实现
    FastBind
    控件非常简单

    基本上,您可以为
    FastBind
    控件创建一个新的
    Control
    类:

    class FastBindConnectionControl implements Control {
        public byte[] getEncodedValue() {
                return null;
        }
        public String getID() {
            return "1.2.840.113556.1.4.1781";
        }
        public boolean isCritical() {
            return true;
        }
    }
    
    然后使用它来创建ldap上下文(错误处理和忽略所有其他内容):

    理想情况下,这将很容易插入SpringLDAP,SpringLDAP是用于LDAP的JNDIAPI的包装器;但是,内置接口似乎不接受处理连接控件的参数,因此您显然需要创建自己的子类来处理该问题,这看起来应该足够简单:

    class FastBindLdapContextSource extends AbstractContextSource {
        protected DirContext getDirContextInstance(Hashtable env) {
            return new InitialLdapContext(env, new Control[] {new FastBindConnectionControl()});
        }
    }
    
    然后,您只需要将当前的
    LdapContextSource
    替换为
    FastBindLdapContextSource
    的实例

    但是,请注意,此上下文源只能用于
    BIND
    操作。正如我在给特里·加德纳的评论中提到的:

    在此模式下,连接上只接受简单绑定。因为没有进行组计算,所以连接总是像没有绑定一样处理