2009-02-23 12 views

Respuesta

1

jespa www.ioplex.com es el único que he encontrado. Nunca lo usaste aunque

3

Para ser honesto, no deberías buscar uno. Para sus necesidades de SSO, debe usar kerberos/SPNEGO correctos en lugar del NTLM heredado.

Para eso no necesita bibliotecas especiales ya que las JVM ya están habilitadas para hacerlo automáticamente. Todo lo que tiene que hacer es configurar su aplicación y las políticas de seguridad de JVM correctamente. La documentación oficial de Sun debe darle todos los detalles que necesita, solo busque la sección "API de seguridad".

+5

NTLM no es un mecanismo "heredado". Se requiere NTLM si el cliente no puede obtener un ticket de Kerberos que desafortunadamente sucede con demasiada facilidad. De hecho, Kerberos es bastante frágil y difícil de usar en comparación. Y NTLMv2 es igual de seguro (128 bits RC4 frente a 256 bits AES realmente no importa mucho). Si necesita hacer NTLM del lado del cliente, JCIFS es completamente funcional (aunque no está totalmente documentado, pregunte en la lista de correo). Si necesita NTLM del lado del servidor, como HTTP SSO, Jespa es el camino a seguir. – user8134

+2

Tenga en cuenta que Jespa no es software libre. –

2

Creo que NTLM está en desuso en favor de Kerberos/SPNEGO. Eche un vistazo al proyecto SPNEGO HTTP Servlet Filter para ver si se ajusta a sus necesidades.

1

Java Opensource Single Sign On (JOSSO) está en http://www.josso.org/ Tienen una página en NTLM, aunque no estoy seguro de qué tan bien funciona.

11

galleta - https://github.com/dblock/waffle

cuenta con filtros, autenticadores, apoya resorte de seguridad, etc. sólo para Windows, pero no requiere DLL nativos.

+0

¡Interesante proyecto! –

+1

Fyi, este proyecto se encuentra ahora en Github - http://github.com/dblock/waffle. –

1

Si no le importa un producto comercialmente empaquetado, eche un vistazo a: Quest Single Sign On for Java, que brinda soporte para SPNEGO/Kerberos (incluidos sitios y protocolos S4U), así como NTLM.

3

Actualmente jcifs es bueno y usted puede probar fácilmente el 4-way handshake localmente con Windows IIS y un zócalo keep alive java.

Esta Apache pseudo code 2004 es útil para construir el algoritmo con JCIFS utilizando generateType1Msg() y generateType3Msg(), incluso Apache promueve un example como una alternativa a HttpClient.

Aparece el código Apache anterior de 2004 pero la autenticación es inestable, obtiene HTTP/1.1 401 Unauthorized con frecuencia, también este código really old de Luigi Dragone ya no funciona. Por otro lado, HttpClient de Apache funciona sin problemas, pero el protocolo de enlace se realiza detrás de la escena (por ejemplo, HttpClient requiere new NTCredentials() para definir la autenticación del usuario).

Aquí hay un ejemplo para probar el protocolo de enlace localmente en IIS, en el puerto 81 sin un dominio. Debe cambiar host, port, user y password y los encabezados HTTP de forma adecuada, eventualmente WWW-Authenticate si no está utilizando IIS.

HTTP/1.1 200 OK significa que la autenticación es correcta; de lo contrario, obtiene 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

Un ejemplo usando HttpURLConnection: http://stackoverflow.com/a/34321230/2073804 – ron190

Cuestiones relacionadas