我有一个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";
}
}
}
由于快速绑定仅“检查用户的凭据”,并且不执行组确定,因此最好使用可分辨名称和凭据将绑定请求发送到服务器。任何简单的绑定请求都应该通过安全连接传输。结果代码为0的响应表示:
无限ID LDAPSDK是与目录服务器交互的最佳Java实现
正如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编码