2009-02-23 34 views

Trả lời

1

jespa www.ioplex.com là người duy nhất tôi gặp phải. Không bao giờ sử dụng nó mặc dù

3

Thành thật mà nói, bạn không nên tìm kiếm. Đối với nhu cầu SSO của bạn, bạn nên sử dụng kerberos thích hợp/SPNEGO thay vì NTLM cũ.

Đối với nội dung đó, bạn không cần thư viện đặc biệt vì JVM đã được bật để tự động thực hiện điều đó. Tất cả những gì bạn phải làm là cấu hình chính sách bảo mật ứng dụng và JVM của mình một cách chính xác. Tài liệu chính thức từ Sun sẽ cung cấp cho bạn tất cả các chi tiết bạn cần, chỉ cần duyệt phần "API bảo mật".

+5

NTLM không phải là cơ chế "cũ". NTLM là bắt buộc nếu khách hàng không thể nhận được một vé Kerberos mà tiếc là xảy ra tất cả quá dễ dàng. Trên thực tế, Kerberos khá mỏng manh và khó sử dụng khi so sánh. Và NTLMv2 chỉ là an toàn (128 bit RC4 so với 256 bit AES thực sự không quan trọng nhiều). Nếu bạn cần thực hiện NTLM phía máy khách, JCIFS có đầy đủ chức năng (mặc dù nó không được viết đầy đủ - hãy hỏi trong danh sách gửi thư). Nếu bạn cần NTLM phía máy chủ chẳng hạn như cho HTTP SSO, thì Jespa là cách để đi. – user8134

+2

Lưu ý rằng Jespa không phải là phần mềm miễn phí. –

2

Tôi nghĩ NTLM không được sử dụng để ủng hộ Kerberos/SPNEGO. Hãy xem dự án SPNEGO HTTP Servlet Filter để xem liệu dự án có phù hợp với nhu cầu của bạn hay không.

1

Đăng nhập một lần mã nguồn mở Java (JOSSO) là http://www.josso.org/ Chúng có một trang trên NTLM, mặc dù tôi không chắc rằng nó hoạt động tốt như thế nào.

11

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

Có bộ lọc, thực hiện chứng thực, hỗ trợ mùa xuân-an ninh, vv Windows-chỉ, nhưng không yêu cầu DLL bản địa.

+0

Dự án thú vị! –

+1

Fyi, dự án này hiện đang ở Github - http://github.com/dblock/waffle. –

1

Nếu bạn không quan tâm đến sản phẩm được đóng gói thương mại, hãy xem: Quest Single Sign On for Java cung cấp hỗ trợ cho SPNEGO/Kerberos (bao gồm các giao thức trang web và giao thức S4U) cũng như NTLM.

3

Trên thực tế jcifs là tốt và bạn có thể kiểm tra dễ dàng 4-way handshake cục bộ bằng Windows IIS và Ổ cắm java vẫn hoạt động.

này 2004 Apache pseudo code rất hữu ích để xây dựng các thuật toán với JCIFS sử dụng generateType1Msg()generateType3Msg(), thậm chí Apache thúc đẩy một example như một thay thế cho HttpClient.

Mã Apache cũ từ năm 2004 công trình nhưng xác thực là không ổn định, bạn sẽ có được HTTP/1.1 401 Unauthorized thường xuyên, cũng really old mã này từ Luigi Dragone không hoạt động nữa. Mặt khác HttpClient của Apache chạy trơn tru nhưng cái bắt tay được thực hiện phía sau cảnh (fyi. HttpClient yêu cầu new NTCredentials() để xác định xác thực của người dùng).

Dưới đây là ví dụ để kiểm tra bắt tay cục bộ trên IIS, trên cổng 81 không có miền. Bạn cần thay đổi các tiêu đề host, port, userpassword và HTTP một cách thích hợp, cuối cùng là WWW-Authenticate nếu bạn không sử dụng IIS.

HTTP/1.1 200 OK nghĩa là xác thực là chính xác, nếu không bạn sẽ nhận được 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

Ví dụ sử dụng HttpURLConnection: http://stackoverflow.com/a/34321230/2073804 – ron190

Các vấn đề liên quan