使用LDAP、Java Play框架通过Active Directory进行身份验证

使用LDAP、Java Play框架通过Active Directory进行身份验证,java,playframework,active-directory,ldap,windows-authentication,Java,Playframework,Active Directory,Ldap,Windows Authentication,我正在尝试使用LDAP通过Windows Active Directory进行身份验证。我有一个LDAPContext类来设置上下文,还有一个应该在广告中找到电子邮件的身份验证方法 这是我的LDAPContext类: public class LDAPContext extends InitialDirContext { Hashtable<String, String> env = new Hashtable<String, String>();

我正在尝试使用LDAP通过Windows Active Directory进行身份验证。我有一个LDAPContext类来设置上下文,还有一个应该在广告中找到电子邮件的身份验证方法

这是我的LDAPContext类:

public class LDAPContext extends InitialDirContext {

    Hashtable<String, String> env = new Hashtable<String, String>();


    public LDAPContext(String email, String password) throws NamingException
    {
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://myintranet.com");
        env.put(Context.SECURITY_AUTHENTICATION,"simple");
        env.put(Context.SECURITY_PRINCIPAL,"mail="+email+"\""); // specify the username
        env.put(Context.SECURITY_CREDENTIALS,password);
        DirContext ctx = new InitialDirContext(env);
    }
}
公共类LDAPContext扩展了InitialDirContext{
Hashtable env=新的Hashtable();
公共LDAPContext(字符串电子邮件、字符串密码)引发NamingException
{
put(Context.INITIAL\u Context\u工厂,“com.sun.jndi.ldap.LdapCtxFactory”);
env.put(Context.PROVIDER\u URL,“ldap://myintranet.com");
环境put(Context.SECURITY_认证,“simple”);
env.put(Context.SECURITY\u PRINCIPAL,“mail=“+email+”\”);//指定用户名
环境放置(上下文、安全性、凭据、密码);
DirContext ctx=新的初始DirContext(env);
}
}
这是我的身份验证方法:

public static User authenticate(final String email, final String password){
    try { 
        LDAPContext adContext = new LDAPContext(email, password);
        Attributes matchAttrs = new BasicAttributes(true);
        matchAttrs.put(new BasicAttribute("mail", email));
        NamingEnumeration<SearchResult> en = adContext.search("", matchAttrs);

       while(en.hasMore()) {
           System.out.println("Found email!!!");
       }
    } catch(NamingException e) {
        System.out.println("NamingException");
    }
...
公共静态用户身份验证(最终字符串电子邮件、最终字符串密码){
试试{
LDAPContext adContext=新的LDAPContext(电子邮件、密码);
Attributes matchAttrs=新的基本属性(true);
matchAttrs.put(新基本属性(“邮件”,电子邮件));
NamingEn=adContext.search(“,matchAttrs);
while(en.hasMore()){
System.out.println(“找到电子邮件!!!”;
}
}捕获(NamingE例外){
System.out.println(“NamingException”);
}
...
我不断收到“NamingException”错误。我确定电子邮件在广告中,指定的电子邮件名称为“mail”。我做错了什么

编辑:这是我得到的具体错误:

javax.naming.AuthenticationException:[LDAP:错误代码49-80090308:LDAPPER:DSID-0C09003A9,注释:AcceptSecurityContext错误,数据52e,v1db1]


这意味着凭据是错误的。我已尝试对其进行硬编码,但仍然不起作用。

问题是您尝试使用的
SECURITY\u PRINCIPAL
值不是可以绑定的有效值。只能绑定用户名,而不能绑定与用户关联的属性

Active directory允许您在
username@domain
或用户帐户的全名。DN值通常类似于

cn=username,cn=Users,dc=abc,dc=mycompany,dc=com
但实际值取决于您的广告配置

如果要通过用户的电子邮件地址查找用户,则需要使用管理员ID(或具有搜索功能的某个ID)进行绑定,使用该特定电子邮件地址搜索用户,然后使用其用户名重新绑定以进行身份验证


此外,这并不是说它改变了什么,而是在绑定名(
“mail=“+email+”\”
)中有一个结束符
但不是开场白。

谢谢你的帮助!凭据/主体现在似乎可以工作了。但现在我遇到另一个错误:
javax.naming.NotContextException:不是DirContext的实例
我尝试过谷歌It,但找不到解决方案。你知道吗?我添加了
env.put(Context.reference,“follow”)
到LDAPClass,现在我没有任何异常。@Kungen:很高兴它能为您工作。虽然我不清楚,但我的答案是否为您解决了问题?您是否做了其他更改处理了它?
NotContextException
通常表示您添加到
哈希表的属性有问题,但在我看来t将
转诊
设置为
遵循
不应该解决问题。无论如何,很高兴它现在对您有效。您的答案解决了部分问题,即
username@domain
尤其重要。但是当我修复了这个错误时,我得到了错误
NotContextException
,设置REFFERAL解决了这个问题。好的,因为您的nswer是解决方案的一部分,我将接受它。谢谢!