java JCIFS NTLM 库的替代品

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/576850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 12:55:06  来源:igfitidea点击:

Alternatives for JCIFS NTLM library

javantlmjcifsjosso

提问by

Are there any alternatives for JCIFS NTLM library?

JCIFS NTLM 库有什么替代品吗?

回答by dB.

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

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

Has filters, authenticators, supports spring-security, etc. Windows-only, but doesn't require native DLLs.

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

回答by ron190

Actually jcifsis good and you can test easily the 4-way handshakelocally with Windows IIS and a keep alive java Socket.

实际上jcifs很好,您可以使用 Windows IIS 和保持活动的 Java 套接字在本地轻松测试4 次握手

This 2004 Apache pseudo codeis useful to build the algorithm with jcifs using generateType1Msg()and generateType3Msg(), even Apache promotes an exampleas an alternative to HttpClient.

这个 2004 Apache伪代码对于使用generateType1Msg()和构建带有 jcifs 的算法很有用generateType3Msg(),甚至 Apache 也推出了一个示例作为 HttpClient 的替代方案。

The old Apache code from 2004 works but authentication is unstable, you get HTTP/1.1 401 Unauthorizedfrequently, also this really oldcode from Luigi Dragone does not work anymore. On the other hand Apache's HttpClient runs smoothly but the handshake is done behind the scene (fyi. HttpClient requires new NTCredentials()to define user's authentication).

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

Here's an example to test the handshake locally on IIS, on port 81 without a domain. You need to change the host, port, userand passwordand HTTP headers appropriately, eventually WWW-Authenticateif you are not using IIS.

这是在 IIS 上本地测试握手的示例,在没有域的端口 81 上。您需要更改的hostportuserpassword和HTTP头得当,最终WWW-Authenticate如果你不使用IIS。

HTTP/1.1 200 OKmeans the authentication is correct, otherwise you get HTTP/1.1 401 Unauthorized.

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());
    }
}

回答by ron190

To be honest, you should not look for one. For your SSO needs you should use proper kerberos / SPNEGO instead of the legacy NTLM.

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

For that stuff you need no special libraries as JVMs are already enabled for doing that automatically. All you have to do is to configure your application and JVM security policies properly. The official documentation from Sun should give you all the details you need, just browse the "security APIs" section.

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

回答by Pat Gonzalez

I think NTLM is being deprecated in favor of Kerberos/SPNEGO. Take a look at the SPNEGO HTTP Servlet Filterproject to see if it might fit your needs.

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

回答by John

Java Opensource Single Sign On (JOSSO) is at http://www.josso.org/They have a page on NTLM, although I'm not sure how well it works.

Java 开源单点登录 (JOSSO) 位于http://www.josso.org/他们有一个关于 NTLM 的页面,尽管我不确定它的工作情况。

回答by Ben Hammond

jespa www.ioplex.comis the only one I've come across. Never used it though

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

回答by Dean Povey

If you don't mind a commercially packaged product then take a look at: Quest Single Sign On for Javawhich provides support for SPNEGO/Kerberos (including sites and S4U protocols) as well as NTLM.

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