Аутентификация против Active Directory с Java на Linux

Попробуйте передать массив в вектор:

int arr[] = {2,5,8,11,14};
std::vector TestVector(arr, arr+5);

Вы всегда можете вызвать std :: vector :: assign , чтобы назначить массив вектору, вызвать std :: vector :: insert для добавления нескольких массивов.

Если вы используете C ++ 11, вы можете попробовать:

std::vector v{2,5,8,11,14};

Или

 std::vector v = {2,5,8,11,14};

73
задан DV. 23 December 2008 в 21:55
поделиться

7 ответов

Вот код, который я соединил на основе примера из этого блога: ССЫЛКА и этот источник: ССЫЛКА .

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();
    }

}
49
ответ дан Emmanuel 7 November 2019 в 07:59
поделиться

Существует 3 протокола аутентификации, которые могут использоваться для выполнения аутентификации между Java и Active Directory на Linux или любой другой платформе (и они не просто характерны для сервисов HTTP):

  1. Kerberos - Kerberos обеспечивает Единую точку входа (SSO) и делегацию, но веб-серверам также нужна поддержка SPNEGO для принятия SSO через IE.

  2. NTLM - NTLM поддерживает SSO через IE (и другие браузеры, если они правильно настроены).

  3. LDAP - который связывает LDAP, может использоваться для простой проверки имени учетной записи и пароля.

существует также что-то позвонившее "ADFS", который обеспечивает SSO для веб-сайтов с помощью SAML, который звонит в Windows SSP так на практике, это - в основном окольный способ использовать один из другого выше протоколов.

Каждый протокол имеет, это - преимущества, но как показывает опыт, для максимальной совместимости необходимо обычно пытаться "сделать, как Windows делает". Таким образом, что делает Windows?

Первый, аутентификация между двумя машинами Windows способствует Kerberos, потому что серверы не должны связываться с DC, и клиенты могут кэшировать билеты Kerberos, который уменьшает нагрузку на DCS (и потому что Kerberos поддерживает делегацию).

, Но если у сторон аутентификации оба нет учетных записей домена или если клиент не может связаться с DC, NTLM требуется. Таким образом, Kerberos и NTLM не являются взаимоисключающими, и NTLM не является obsoleted Kerberos. На самом деле до некоторой степени NTLM лучше, чем Kerberos. Обратите внимание, что при упоминании Kerberos и NTLM на одном дыхании я должен также упомянуть SPENGO и Интегрированную аутентификацию Windows (IWA). IWA является простым термином, который в основном означает Kerberos или NTLM или SPNEGO согласовывать Kerberos или NTLM.

Используя LDAP связывают, поскольку способ проверить учетные данные не эффективен и требует SSL. Но до недавнего времени реализация Kerberos и NTLM была трудной настолько использующий LDAP, поскольку импровизированная услуга аутентификации сохранилась. Но в этой точке этого нужно обычно избегать. LDAP является каталогом информации и не услуги аутентификации. Используйте его, поскольку это предназначило цель.

Поэтому, как Вы реализуете Kerberos или NTLM в Java и в контексте веб-приложений в особенности?

существует много крупных компаний как Quest Software и Centrify, которые имеют решения, это конкретно упоминает Java. Я не могу действительно прокомментировать их, поскольку они - общекорпоративные "решения по управлению идентификационных данных" так от взгляда маркетингового вращения на их веб-сайте, трудно сказать точно, какие протоколы используются и как. Необходимо было бы связаться с ними для деталей.

Реализация Kerberos в Java не ужасно тверд, поскольку стандартные библиотеки Java поддерживают Kerberos через org.ietf.gssapi классы. Однако до недавнего времени было главное препятствие - IE не отправляет необработанные маркеры Kerberos, это отправляет маркеры SPNEGO. Но с Java 6, был реализован SPNEGO. В теории необходимо быть в состоянии записать некоторый код GSSAPI, который может аутентифицировать клиенты IE. Но я не попробовал его. Реализация Sun Kerberos была комедией ошибок за эти годы так на основе послужного списка Sun в этой области, я не сделал бы обещаний об их реализации SPENGO, пока у Вас нет той птицы в руке.

Для NTLM, существует Бесплатный проект OSS под названием JCIFS, который имеет Фильтр Сервлета Аутентификации HTTP NTLM. Однако это использует man-in-the-middle метод для проверки учетных данных с сервером SMB, который не работает с NTLMv2 (который медленно становится необходимой политикой безопасности домена). По этой причине и другие, часть HTTP-фильтра JCIFS, как планируют, будет удалена. Обратите внимание, что существует количество ответвлений, которые используют JCIFS для реализации той же техники. Таким образом, если Вы видите другие проекты, которые утверждают, что поддерживали NTLM SSO, проверили мелкий шрифт.

единственный корректный способ проверить учетные данные NTLM с Active Directory использует СЕТЕВОЙ ВХОД В СИСТЕМУ переклички NetrLogonSamLogon DCERPC с Безопасным каналом. Такая вещь существует в Java? Да. Здесь это:

http://www.ioplex.com/jespa.html

Jespa составляет 100% Java реализация NTLM, которая поддерживает NTLMv2, NTLMv1, полные опции целостности и конфиденциальности и вышеупомянутую учетную проверку СЕТЕВОГО ВХОДА В СИСТЕМУ. И это включает Фильтр SSO HTTP, JAAS LoginModule, клиент HTTP, клиент и сервер SASL (с JNDI, связывающим), универсальный "поставщик систем обеспечения безопасности" для создания пользовательских сервисов NTLM и т.д.

Mike

96
ответ дан user8134 7 November 2019 в 07:59
поделиться

Я только что закончил проект, который использует AD и Java. Мы использовали Spring ldapTemplate.

AD LDAP совместимый (почти), я не думаю, что у Вас будут любые проблемы с задачей, которую Вы имеете. Я имею в виду то, что это - AD или любой другой сервер LDAP, не имеет значения, если Вы хотите только соединиться.

я смотрел бы на: Spring LDAP

у Них есть примеры также.

Что касается шифрования, мы использовали соединение SSL (таким образом, это был LDAPS). AD должен был быть настроен на порте/протоколе SSL.

, Но в первую очередь, удостоверьтесь, что можно правильно соединиться с AD через IDE LDAP. Я использую каталог Studio Apache, это действительно прохладно, и это записано в Java. Это - все, в чем я нуждался. Для тестирования Вы могли также установить Сервер каталогов

Apache
6
ответ дан James B 7 November 2019 в 07:59
поделиться

Вы просто проверяете учетные данные? В этом случае Вы могли просто сделать плоскость kerberos и не обеспокоиться LDAP.

3
ответ дан Mamun 7 November 2019 в 07:59
поделиться
1
ответ дан Mash See 7 November 2019 в 07:59
поделиться

Если все, что вам нужно сделать, это пройти аутентификацию в AD с использованием Kerberos, то это должна сделать простая программа http://spnego.sourceforge.net/HelloKDC.java .

Взгляните на «предполетную» документацию проекта, в которой говорится о программе HelloKDC.java.

2
ответ дан 24 November 2019 в 12:15
поделиться

Как сказали ioplex и другие, есть много вариантов. Для аутентификации с использованием LDAP (и Novell LDAP API) я использовал что-то вроде:


LDAPConnection connection = new LDAPConnection( new LDAPJSSEStartTLSFactory() );
connection.connect(hostname, port);
connection.startTLS();
connection.bind(LDAPConnection.LDAP_V3, username+"@"+domain, password.getBytes());

В качестве «специальной функции» Active Directory позволяет связываться LDAP с « user @ domain(Код, выполняющий проверку, может связаться с сервером AD для проверки имени пользователя и пароля, что приведет к выдаче билета для пользователя, но чтобы убедиться, что сервер AD не олицетворяется, ему также необходимо попытаться получить билет для пользователь сам себе, что несколько сложнее.)

Если вы хотите использовать единый вход на основе Kerberos, предполагая, что ваши пользователи аутентифицированы в домене, вы также можете сделать это с помощью кода Java GSS-API . Я бы опубликовал образец кода, но мне все еще нужно превратить свой ужасный прототип во что-то подходящее для человеческого глаза. Посмотрите код из SpringSource для вдохновения.

Если вы ищете NTLM (который, как я понял, менее безопасен) или что-то еще, что ж, удачи.

но чтобы гарантировать, что сервер AD не олицетворяется, он также должен попытаться получить билет для пользователя, что несколько сложнее.)

Если вы хотите использовать единый вход на основе Kerberos, предполагая ваши пользователи аутентифицированы в домене, вы также можете сделать это с помощью кода Java GSS-API. Я бы опубликовал образец кода, но мне все еще нужно превратить свой ужасный прототип во что-то подходящее для человеческого глаза. Посмотрите код из SpringSource для вдохновения.

Если вы ищете NTLM (который, как мне показалось, менее безопасен) или что-то еще, что ж, удачи.

но чтобы гарантировать, что сервер AD не олицетворяется, ему также необходимо попытаться получить билет для пользователя, что несколько сложнее.)

Если вы хотите использовать единый вход на основе Kerberos, предполагая ваши пользователи аутентифицированы в домене, вы также можете сделать это с помощью кода Java GSS-API. Я бы опубликовал образец кода, но мне все еще нужно превратить свой ужасный прототип во что-то подходящее для человеческого глаза. Посмотрите код из SpringSource для вдохновения.

Если вы ищете NTLM (который, как я понял, менее безопасен) или что-то еще, что ж, удачи.

предполагая, что ваши пользователи аутентифицированы в домене, вы также можете сделать это с помощью кода Java GSS-API. Я бы опубликовал образец кода, но мне все еще нужно превратить свой ужасный прототип во что-то подходящее для человеческого глаза. Посмотрите код из SpringSource для вдохновения.

Если вы ищете NTLM (который, как мне показалось, менее безопасен) или что-то еще, что ж, удачи.

предполагая, что ваши пользователи аутентифицированы в домене, вы также можете сделать это с помощью кода Java GSS-API. Я бы опубликовал образец кода, но мне все еще нужно превратить свой ужасный прототип во что-то подходящее для человеческого глаза. Посмотрите код из SpringSource для вдохновения.

Если вы ищете NTLM (который, как мне показалось, менее безопасен) или что-то еще, что ж, удачи.

5
ответ дан 24 November 2019 в 12:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: