【问题标题】:Alternatives for JCIFS NTLM libraryJCIFS NTLM 库的替代品
【发布时间】:2010-10-09 06:39:03
【问题描述】:

JCIFS NTLM 库有什么替代品吗?

【问题讨论】:

  • 请在我对this问题的回答中查看我的建议。

标签: java ntlm jcifs josso


【解决方案1】:

华夫饼 - https://github.com/dblock/waffle

具有过滤器、身份验证器、支持 spring-security 等。仅限 Windows,但不需要本机 DLL。

【讨论】:

    【解决方案2】:

    实际上jcifs 很好,您可以使用Windows IIS 和keep alive java Socket 在本地轻松测试4-way handshake

    这个 2004 Apache pseudo code 对于使用 generateType1Msg()generateType3Msg() 的 jcifs 构建算法很有用,甚至 Apache 也提倡使用 example 作为 HttpClient 的替代方案。

    2004 年的旧 Apache 代码可以工作,但身份验证不稳定,您经常收到 HTTP/1.1 401 Unauthorized,Luigi Dragone 的这个 really old 代码也不再工作了。另一方面,Apache 的 HttpClient 运行平稳,但握手是在幕后完成的(仅供参考。HttpClient 需要new NTCredentials() 来定义用户的身份验证)。

    这是一个在 IIS 上本地测试握手的示例,在没有域的端口 81 上。您需要适当地更改 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());
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果您不介意商业包装产品,请查看:Quest Single Sign On for Java,它提供对 SPNEGO/Kerberos(包括站点和 S4U 协议)以及 NTLM 的支持。

      【讨论】:

        【解决方案4】:

        Java 开源单点登录 (JOSSO) 位于 http://www.josso.org/ 他们有一个关于 NTLM 的页面,虽然我不确定它的效果如何。

        【讨论】:

          【解决方案5】:

          我认为 NTLM 已被弃用,取而代之的是 Kerberos/SPNEGO。查看SPNEGO HTTP Servlet Filter 项目,看看它是否符合您的需求。

          【讨论】:

            【解决方案6】:

            说实话,你不应该寻找一个。对于您的 SSO 需求,您应该使用适当的 kerberos / SPNEGO 而不是旧版 NTLM。

            对于这些东西,您不需要特殊的库,因为 JVM 已经启用自动执行此操作。您所要做的就是正确配置您的应用程序和 JVM 安全策略。 Sun 的官方文档应该为您提供所需的所有详细信息,只需浏览“安全 API”部分。

            【讨论】:

            • NTLM 不是“传统”机制。如果客户端无法获得 Kerberos 票证,不幸的是这太容易发生了,则需要 NTLM。事实上,相比之下,Kerberos 相当脆弱且难以使用。 NTLMv2 也同样安全(1​​28 位 RC4 与 256 位 AES 真的无关紧要)。如果您需要执行客户端 NTLM,JCIFS 功能齐全(尽管没有完整记录 - 请在邮件列表中询问)。如果您需要服务器端 NTLM,例如 HTTP SSO,Jespa 是您的最佳选择。
            • 请注意,Jespa 不是免费软件。
            【解决方案7】:

            jespa www.ioplex.com 是我遇到的唯一一个。 不过没用过

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2012-02-12
              • 2011-09-03
              • 2013-06-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-12-31
              相关资源
              最近更新 更多