当前位置: 首页 > 知识库问答 >
问题:

使用Spring LDAP针对Active Directory进行身份验证的FastBind

敖毅
2023-03-14

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

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

谢谢

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

根据@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;
    }
}

然后,我使用连接控制类扩展了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>

最后,将userAuthenticationService注入客户机类,比如登录控制器。

package com.company.web;

import com.company.authentication;

@Controller
public class LoginController {

    @Autowired
    private IAuthenticate userAuthenticationService;

    public String authenticateUser(String login, String password) {
      if (this.userAuthenticationService.authenticate(login, password)) {
          return "welcome";
      }
      else {
        return "login";
      }
    }
}

共有2个答案

景志
2023-03-14

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

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

无限ID LDAPSDK是与目录服务器交互的最佳Java实现

慕容安易
2023-03-14

正如OTN论坛帖子中所讨论的,在JNDI中实现FastBind控件非常简单。

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

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上下文(错误处理和忽略其他所有内容):

LdapContext ctx = new InitialLdapContext(env, new Control[] {new FastBindConnectionControl()});

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

class FastBindLdapContextSource extends AbstractContextSource {
    protected DirContext getDirContextInstance(Hashtable env) {
        return new InitialLdapContext(env, new Control[] {new FastBindConnectionControl()});
    }
}

然后,您只需要将当前的LdapContextSource替换为FastBindLdapContextSource的实例。

但是,请注意,此上下文源只能用于绑定操作。正如我在给Terry Gardner的评论中链接到的MSDN文件中所指出的:

在此模式下,连接上只接受简单绑定。由于没有进行组评估,因此连接的处理始终如同所有其他LDAP操作都没有进行绑定一样。

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

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

但是,假设您获得了对ADContextSource bean的引用,它应该足够简单,可以执行以下操作

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,如果您想要这种行为,可以很容易地添加)。

 类似资料:
  • 问题内容: 如何使用Python + LDAP针对AD进行身份验证。我目前正在使用python-ldap库,它所产生的只是眼泪。 我什至不能绑定执行简单的查询: 运行此命令会给我两个错误之一: -输入错误或故意使用错误的凭据时,它无法通过身份验证。 ldap.INVALID_CREDENTIALS:{‘info’:‘80090308:LdapErr:DSID-0C090334,评论:AcceptS

  • 我卡住试图弄清楚如何通过使用此留档给出的REST api来验证用户访问JIRA的JSON数据:https://developer.atlassian.com/server/jira/platform/jira-rest-api-example-basic-authentication-6291732/ Items是一个数组,它允许我从jira获取URL提供的JSON数据中的值。 我无法接收数据,因

  • 我正在尝试使用urllib3连接到网页。代码如下所示。 如果我们假设url是需要使用用户名和密码进行身份验证的某个网页,那么我是否使用正确的代码进行身份验证? 我使用urllib2做这件事很舒服,但使用urllib3做不到同样的事情。 非常感谢

  • jwt不应该仅仅用于认证用户吗?我读到过可以在里面存储非敏感的东西,比如用户ID。将权限级别之类的东西存储在令牌中可以吗?这样我可以避免数据库调用。

  • 问题内容: 我可以通过接收到请求的xml 但不是 没有JavaScript错误,没有跨域策略问题。可能是语法错误,但是我找不到合适的教程。有什么建议吗? 问题答案: 我认为您需要纯格式:

  • 我是全新的RestTemboard和基本上在REST API也。我想通过Jira REST API检索我的应用程序中的一些数据,但取回401未经授权。在jira rest api留档上找到并发表文章,但不知道如何将其重写为java,因为示例使用curl的命令行方式。我将感谢任何建议或建议如何重写: 进入java使用SpringRest模板。其中ZnJlZDpmcmVk是用户名:密码的Bas64编码