2009-02-23 9 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シングルサインオン(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とkeep alive java Socketでローカルで簡単にテストできます。

は、この2004年のApache pseudo codegenerateType1Msg()generateType3Msg()を使用してJCIFSとアルゴリズムを構築するのに便利です、でも、ApacheはHttpClientを代替としてexampleを推進しています。

2004年の古いApacheコードは動作しますが、認証が不安定な場合、HTTP/1.1 401 Unauthorizedが頻繁に発生し、Luigi Dragoneのこのreally oldコードはもう動作しません。一方、ApacheのHttpClientはスムーズに動作しますが、ハンドシェイクはその場で行われます(ユーザーの認証を定義するにはHttpClientにはnew NTCredentials()が必要です)。

ここでは、ドメインなしでポート81でIIS上でハンドシェイクをローカルにテストする例を示します。 hostportuserpasswordと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