在 Linux 上使用 Java 对 Active Directory 进行身份验证 [英] Authenticating against Active Directory with Java on Linux

查看:30
本文介绍了在 Linux 上使用 Java 对 Active Directory 进行身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 Java 对 Active Directory 进行身份验证的简单任务.只是验证凭据而已.假设我的域是fun.xyz.tld",OU 路径未知,用户名/密码是 testu/testp.

I have a simple task of authenticating against Active Directory using Java. Just verifying credentials and nothing else. Let's say my domain is "fun.xyz.tld", OU path is unknown, and username/password is testu/testp.

我知道有一些 Java 库可以简化这项任务,但我没有成功实现它们.我发现的大多数示例一般都针对 LDAP,而不是专门针对 Active Directory.发出 LDAP 请求意味着在其中发送一个 OU 路径,而我没有.此外,发出 LDAP 请求的应用程序应该已经绑定到 Active Directory 才能访问它......不安全,因为凭据必须存储在某个可发现的地方.如果可能的话,我想要一个带有测试凭据的测试绑定 - 这意味着该帐户是有效的.

I know there's a few Java libraries out there that simplify this task, but I wasn't successful at implementing them. Most examples that I've found addressed LDAP in general, not specifically Active Directory. Issuing LDAP request means sending an OU path in it, which I don't have. Also, the application that issues LDAP request should be already bound to Active Directory in order to access it... Insecure, since the credentials would have to be stored someplace discoverable. I would like a test bind with test credentials, if possible - this would mean that account is valid.

最后,如果可能的话,有没有办法使这种身份验证机制加密?我知道 AD 使用 Kerberos,但不确定 Java 的 LDAP 方法是否使用.

Last, if possible, is there a way to make such authentication mechanism encrypted? I know that AD uses Kerberos, but not sure if Java's LDAP methods do.

有人有工作代码的例子吗?谢谢.

Does anyone has an example of working code? Thanks.

推荐答案

以下是我根据此博客中的示例编写的代码:LINK 和这个来源:LINK.

Here's the code I put together based on example from this blog: LINK and this source: LINK.

import com.sun.jndi.ldap.LdapCtxFactory;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Iterator;
import javax.naming.Context;
import javax.naming.AuthenticationException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import static javax.naming.directory.SearchControls.SUBTREE_SCOPE;

class App2 {

    public static void main(String[] args) {

        if (args.length != 4 && args.length != 2) {
            System.out.println("Purpose: authenticate user against Active Directory and list group membership.");
            System.out.println("Usage: App2 <username> <password> <domain> <server>");
            System.out.println("Short usage: App2 <username> <password>");
            System.out.println("(short usage assumes 'xyz.tld' as domain and 'abc' as server)");
            System.exit(1);
        }

        String domainName;
        String serverName;

        if (args.length == 4) {
            domainName = args[2];
            serverName = args[3];
        } else {
            domainName = "xyz.tld";
            serverName = "abc";
        }

        String username = args[0];
        String password = args[1];

        System.out
                .println("Authenticating " + username + "@" + domainName + " through " + serverName + "." + domainName);

        // bind by using the specified username/password
        Hashtable props = new Hashtable();
        String principalName = username + "@" + domainName;
        props.put(Context.SECURITY_PRINCIPAL, principalName);
        props.put(Context.SECURITY_CREDENTIALS, password);
        DirContext context;

        try {
            context = LdapCtxFactory.getLdapCtxInstance("ldap://" + serverName + "." + domainName + '/', props);
            System.out.println("Authentication succeeded!");

            // locate this user's record
            SearchControls controls = new SearchControls();
            controls.setSearchScope(SUBTREE_SCOPE);
            NamingEnumeration<SearchResult> renum = context.search(toDC(domainName),
                    "(& (userPrincipalName=" + principalName + ")(objectClass=user))", controls);
            if (!renum.hasMore()) {
                System.out.println("Cannot locate user information for " + username);
                System.exit(1);
            }
            SearchResult result = renum.next();

            List<String> groups = new ArrayList<String>();
            Attribute memberOf = result.getAttributes().get("memberOf");
            if (memberOf != null) {// null if this user belongs to no group at all
                for (int i = 0; i < memberOf.size(); i++) {
                    Attributes atts = context.getAttributes(memberOf.get(i).toString(), new String[] { "CN" });
                    Attribute att = atts.get("CN");
                    groups.add(att.get().toString());
                }
            }

            context.close();

            System.out.println();
            System.out.println("User belongs to: ");
            Iterator ig = groups.iterator();
            while (ig.hasNext()) {
                System.out.println("   " + ig.next());
            }

        } catch (AuthenticationException a) {
            System.out.println("Authentication failed: " + a);
            System.exit(1);
        } catch (NamingException e) {
            System.out.println("Failed to bind to LDAP / get account information: " + e);
            System.exit(1);
        }
    }

    private static String toDC(String domainName) {
        StringBuilder buf = new StringBuilder();
        for (String token : domainName.split("\.")) {
            if (token.length() == 0)
                continue; // defensive check
            if (buf.length() > 0)
                buf.append(",");
            buf.append("DC=").append(token);
        }
        return buf.toString();
    }

}

这篇关于在 Linux 上使用 Java 对 Active Directory 进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆