2009-02-23 3 views

답변

1

jespa www.ioplex.com은 제가 만난 유일한 것입니다. 사용하지 마십시오.

3

솔직히 말하면, 찾아 보지 마십시오. SSO 요구 사항에 대해 기존 NTLM 대신 적절한 kerberos/SPNEGO를 사용해야합니다.

JVM이 이미 자동으로 활성화되어 있으므로 특별한 라이브러리가 필요하지 않습니다. 응용 프로그램과 JVM 보안 정책을 올바르게 구성하기 만하면됩니다. Sun의 공식 문서를 통해 필요한 모든 세부 정보를 얻을 수 있습니다. "보안 API"섹션을 찾아보십시오.

+5

NTLM은 "레거시"메커니즘이 아닙니다. 클라이언트가 불행하게도 너무 쉽게 발생하는 Kerberos 티켓을 얻을 수 없으면 NTLM이 필요합니다. 사실, Kerberos는 다소 취약하고 사용하기가 어렵습니다. 그리고 NTLMv2는 안전합니다 (128 비트 RC4 대 256 비트 AES는별로 중요하지 않습니다). 클라이언트 측 NTLM을 수행해야하는 경우 JCIFS는 완벽하게 문서화되지는 않았지만 메일 링리스트에서 요청하십시오. HTTP SSO와 같은 서버 측 NTLM이 필요한 경우 Jespa를 사용하십시오. – user8134

+2

Jespa는 자유 소프트웨어가 아닙니다. –

2

나는 NTLM이 Kerberos/SPNEGO에 찬성하여 더 이상 사용되지 않을 것이라고 생각합니다. SPNEGO HTTP Servlet Filter 프로젝트를보고 자신의 필요에 맞는지 확인하십시오.

1

Java Opensource 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

상용 패키지 제품에 신경 쓰지 않는다면 NTLM뿐 아니라 SPNEGO/Kerberos (사이트 및 S4U 프로토콜 포함)를 지원하는 Quest Single Sign On for Java을 살펴보십시오.

3

실제로는 jcifs이 좋으므로 로컬로 Windows IIS와 keep alive java Socket을 사용하여 4-way handshake을 쉽게 테스트 할 수 있습니다.

이 2004 아파치 pseudo codegenerateType1Msg()generateType3Msg()를 사용 JCIFS와 알고리즘을 구축하는 데 유용합니다, 심지어 아파치 HttpClient를 대안으로서 example을 촉진합니다.

2004 년 이전 Apache 코드가 작동하지만 인증이 불안정한 경우 HTTP/1.1 401 Unauthorized이 자주 발생하며 Luigi Dragone의이 really old 코드가 더 이상 작동하지 않습니다. 반면에 Apache의 HttpClient는 부드럽게 실행되지만 핸드 셰이크는 현장에서 수행됩니다 (사용자의 인증을 정의하려면 HttpClient가 new NTCredentials() 필요).

다음은 도메인이없는 포트 81에서 IIS에서 로컬로 핸드 셰이크를 테스트하는 예제입니다. host, port, userpassword 및 HTTP 헤더를 적절하게 변경해야하며, IIS를 사용하지 않는 경우에는 결국 WWW-Authenticate으로 변경해야합니다.

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