2009-02-23 3 views

ответ

1

jespa www.ioplex.com - единственный, с которым я столкнулся. Никогда не использовал его, хотя

3

Чтобы быть честным, вы не должны его искать. Для ваших потребностей SSO вы должны использовать надлежащие kerberos/SPNEGO вместо устаревшего NTLM.

Для этого вам не нужны специальные библиотеки, поскольку JVM уже включены для этого автоматически. Все, что вам нужно сделать, - это правильно настроить политики безопасности приложений и JVM. Официальная документация от Sun должна предоставить вам всю необходимую информацию, просто просмотрите раздел «API безопасности».

+5

NTLM не является «устаревшим» механизмом. NTLM требуется, если клиент не может получить билет Kerberos, который, к сожалению, слишком легко выполняется. На самом деле Kerberos довольно хрупкий и сложный в использовании по сравнению. И NTLMv2 столь же безопасен (128 бит RC4 против 256 бит AES действительно не имеет большого значения). Если вам нужно сделать NTLM на стороне клиента, JCIFS полностью функциональен (хотя он не полностью задокументирован - спросите в списке рассылки). Если вам нужен серверный NTLM, такой как HTTP SSO, Jespa - это путь. – user8134

+2

Обратите внимание, что Jespa не является свободным программным обеспечением. –

2

Я думаю, что NTLM устарел в пользу Kerberos/SPNEGO. Взгляните на проект SPNEGO HTTP Servlet Filter, чтобы узнать, может ли он соответствовать вашим потребностям.

1

Java Single Sign On (JOSSO) находится на http://www.josso.org/ У них есть страница на NTLM, хотя я не уверен, насколько хорошо она работает.

11

Вафля - https://github.com/dblock/waffle

Имеет фильтры, аутентификаторы, поддерживает пружинную безопасность и т.д. Windows, только, но не требует нативных библиотек DLL.

+0

Интересный проект! –

+1

Fyi, этот проект теперь находится в Github - http://github.com/dblock/waffle. –

1

Если вы не против коммерчески упакованного продукта, посмотрите на: Quest Single Sign On for Java, который обеспечивает поддержку SPNEGO/Kerberos (включая сайты и протоколы S4U), а также NTLM.

3

Фактически jcifs - это хорошо, и вы можете легко тестировать 4-way handshake локально с Windows IIS и поддерживать Java Socket.

Это 2004 Apache pseudo code полезно построить алгоритм с использованием JCIFS generateType1Msg() и generateType3Msg(), даже Apache способствует example в качестве альтернативы HttpClient.

Старый код Apache с 2004 года работает, но аутентификация нестабильна, вы часто получаете HTTP/1.1 401 Unauthorized, также этот код really old от Luigi Dragone больше не работает. С другой стороны, Apache HttpClient работает плавно, но рукопожатие выполняется за сценой (для определения аутентификации пользователя требуется HttpClient new NTCredentials()).

Вот пример, чтобы проверить рукопожатие локально на IIS, на порту 81 без домена. Вам необходимо изменить host, port, user и password и заголовки HTTP соответственно, в конечном итоге WWW-Authenticate, если вы не используете IIS.

HTTP/1.1 200 OK означает, что аутентификация верна, иначе вы получите HTTP/1.1 401 Unauthorized.

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.OutputStreamWriter; 
import java.net.Socket; 
import java.net.UnknownHostException; 

import jcifs.ntlmssp.NtlmFlags; 
import jcifs.ntlmssp.Type1Message; 
import jcifs.ntlmssp.Type2Message; 
import jcifs.ntlmssp.Type3Message; 
import jcifs.util.Base64; 

import org.apache.http.impl.auth.NTLMEngineException; 

public class TestNTLM { 

    public static void main(String[] args) throws UnknownHostException, IOException, NTLMEngineException { 
     Socket s = new Socket("127.0.0.1", 81); 
     s.setKeepAlive(true); 
     InputStream is = s.getInputStream(); 
     OutputStream os = s.getOutputStream(); 
     BufferedReader r = new BufferedReader(new InputStreamReader(is)); 
     BufferedWriter w = new BufferedWriter(new OutputStreamWriter(os)); 

     String host = "127.0.0.1:81"; 
     String hostDomain = ""; 
     String user = "My_Windows_Username"; 
     String password = "My_Windows_Password"; 

     w.write("GET http://127.0.0.1:81/ HTTP/1.1\n"); 
     w.write("Host: 127.0.0.1:81\n"); 
     w.write("Authorization: NTLM " + TestNTLM.generateType1Msg(hostDomain, host) + "\n\n"); 
     System.out.println("[First Message Sent]"); 
     w.flush(); 

     String resp = "", line = ""; 
     int contentLength = 0; 
     while((line = r.readLine()) != null){ 
      if(line.length() == 0) 
       break; 
      System.out.println(line); 
      if(line.startsWith("Content-Length")) 
       contentLength = Integer.parseInt(line.substring(line.indexOf(":") + 1).trim()); 
      else if(line.startsWith("WWW-Authenticate")) 
       resp = line.substring(line.indexOf(":") + 1).trim(); 
     } 
     r.skip(contentLength); 

     System.out.println("\n[Second Message Received]"); 
     System.out.println("Proxy-Authenticate: " + resp); 
     resp = resp.substring(resp.indexOf(" ")).trim(); 

     w.write("GET http://127.0.0.1:81/ HTTP/1.1\n"); 
     w.write("Host: 127.0.0.1:81\n"); 
     w.write("Authorization: NTLM " + TestNTLM.generateType3Msg(user, password, hostDomain, host, new String(resp)) + "\n\n"); 

     w.flush(); 
     System.out.println("\n[Third Message Sent]"); 

     while((line = r.readLine()) != null){ 
      System.out.println(line); 
      if(line.length() == 0) 
       break; 
     } 
    } 

    private static final int TYPE_1_FLAGS = 
      NtlmFlags.NTLMSSP_NEGOTIATE_56 | 
      NtlmFlags.NTLMSSP_NEGOTIATE_128 | 
      NtlmFlags.NTLMSSP_NEGOTIATE_NTLM2 | 
      NtlmFlags.NTLMSSP_NEGOTIATE_ALWAYS_SIGN | 
      NtlmFlags.NTLMSSP_REQUEST_TARGET; 

    public static String generateType1Msg(final String domain, final String workstation) 
      throws NTLMEngineException { 
     final Type1Message type1Message = new Type1Message(TYPE_1_FLAGS, domain, workstation); 
     return Base64.encode(type1Message.toByteArray()); 
    } 

    public static String generateType3Msg(final String username, final String password, 
      final String domain, final String workstation, final String challenge) 
        throws NTLMEngineException { 
     Type2Message type2Message; 
     try { 
      type2Message = new Type2Message(Base64.decode(challenge)); 
     } catch (final IOException exception) { 
      throw new NTLMEngineException("Invalid NTLM type 2 message", exception); 
     } 
     final int type2Flags = type2Message.getFlags(); 
     final int type3Flags = type2Flags 
       & (0xffffffff^(NtlmFlags.NTLMSSP_TARGET_TYPE_DOMAIN | NtlmFlags.NTLMSSP_TARGET_TYPE_SERVER)); 
     final Type3Message type3Message = new Type3Message(type2Message, password, domain, 
       username, workstation, type3Flags); 
     return Base64.encode(type3Message.toByteArray()); 
    } 
} 
+1

Пример использования HttpURLConnection: http://stackoverflow.com/a/34321230/2073804 – ron190