Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
ntlm身份验证的Java URLConnection错误,但仅在Linux和Java 7上_Java_Authentication_Ntlm_Urlconnection - Fatal编程技术网

ntlm身份验证的Java URLConnection错误,但仅在Linux和Java 7上

ntlm身份验证的Java URLConnection错误,但仅在Linux和Java 7上,java,authentication,ntlm,urlconnection,Java,Authentication,Ntlm,Urlconnection,我正在尝试打开一个到受NTLM身份验证方案保护的url的http连接。当我们使用Java6时,这段代码已经正常工作了2年。我编写了一个小型Java程序,可以访问特定的url,使测试用例尽可能简单 问题是,我无法使该程序在linux和使用JDK 7版本时工作。Java尝试了20次访问URL,然后我得到一个错误,告诉我服务器重定向了太多次。它适用于linux和JDK 6,在windows 7中适用于JDK 6或7 我检查并尝试了此处列出的解决方案(以及其他许多解决方案):。它不起作用。我还必须补充一

我正在尝试打开一个到受NTLM身份验证方案保护的url的http连接。当我们使用Java6时,这段代码已经正常工作了2年。我编写了一个小型Java程序,可以访问特定的url,使测试用例尽可能简单

问题是,我无法使该程序在linux和使用JDK 7版本时工作。Java尝试了20次访问URL,然后我得到一个错误,告诉我服务器重定向了太多次。它适用于linux和JDK 6,在windows 7中适用于JDK 6或7

我检查并尝试了此处列出的解决方案(以及其他许多解决方案):。它不起作用。我还必须补充一点,当从浏览器访问url时,我可以看到没有涉及cookies

以下是我尝试过的os/java版本的详细信息:

成功:

  • Windows 7:Java(TM)SE运行时环境(build 1.7.0_15-b03)(64位)
  • Windows 7:Java(TM)SE运行时环境(build 1.7.0_10-b18)(64位)
  • Windows 7:Java(TM)SE运行时环境(build 1.6.0_33-b04)(64位)
  • Redhat enterprise linux 6.4:Java(TM)SE运行时环境(build 1.6.0_33-b04)(64位)
失败:

  • Redhat enterprise linux 6.4:Java(TM)SE运行时环境(版本1.7.0-b147)(64位)
  • Redhat enterprise linux 6.4:Java(TM)SE运行时环境(build 1.7.0_05-b06)(64位)
  • Redhat enterprise linux 6.4:Java(TM)SE运行时环境(build 1.7.0_13-b20)(64位)
  • Redhat enterprise linux 6.4:Java(TM)SE运行时环境(build 1.7.0_15-b03)(64位)
当程序运行时,我会看到使用的身份验证方法以及我试图下载的文档作为输出:

Scheme:Negotiate
Scheme:ntlm
.... document content ....
Done
当它失败时,我有以下输出:

Scheme:Negotiate
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
Scheme:ntlm
java.net.ProtocolException: Server redirected too many  times (20)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1635)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
        at TestWs.testWs(TestWs.java:67)
        at TestWs.main(TestWs.java:20)
以下是该程序的源代码:

package com.test;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.URLConnection;

public class TestWs {

    public static void main(String[] args) throws Exception {
        new TestWs().testWs();
    }

    public void testWs() {
        try {
            CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
            Authenticator.setDefault(new MyAuthenticator("username", "password"));

            URL url = new URL("https://someurlprotectedbyntlmauthentication.com");
            URLConnection connection = url.openConnection();
            InputStream is = connection.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            while (true) {
                String s = br.readLine();
                if (s == null)
                    break;
                System.out.println(s);
            }
            System.out.println("Done");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

class MyAuthenticator extends Authenticator {
    private String httpUsername;
    private String httpPassword;

    public MyAuthenticator(String httpUsername, String httpPassword) {
        this.httpUsername = httpUsername;
        this.httpPassword = httpPassword;
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        System.out.println("Scheme:" + getRequestingScheme());
        return new PasswordAuthentication(httpUsername, httpPassword.toCharArray());
    }
}
任何帮助都将不胜感激

更新:

经过进一步的调查,我发现如果我使用域用户,身份验证就有效,但如果我使用本地用户,身份验证就无效

来自JDK 7的代码给我带来了麻烦(class com.sun.security.ntlm.Client):

因此,由于服务器是在域中注册的,因此它将其域作为NTLM协议的一部分发送回客户端。Java每次都会用变量“domainFromServer”替换我试图强制的域,但它失败了,因为用户存在于服务器上,而不是服务器的域上


我不知道该怎么办。

我更改了Client.java类中的代码,并将其与com.sun.security.ntlm包的其余部分一起重新编译,然后创建了一个名为rt_fix.jar的jar,其中包含该特定包的类。然后,我使用java启动选项强制它在内部rt.jar之前加载我的jar

-Xbootclasspath/p:/path\u to\u jar/rt\u fix.jar

我不喜欢这个解决方案,但它奏效了

以下是我在Client.java中更改的代码,方法类型为3:

之前:

    if (domainFromServer != null) {
        domain = domainFromServer;
    }
之后:

    if (domainFromServer != null) {
        //domain = domainFromServer;
    }

它阻止Java在发送NTLM身份验证的第三部分时,使用从服务器接收到的域更改我尝试进行身份验证的域。我试图验证的域实际上是服务器的名称,因为用户帐户是本地的。

我遇到了同样的问题,只需指定包含域的用户名即可解决:

    Authenticator.setDefault(new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(
                    System.getProperty("DOMAIN\\user"),
                    System.getProperty("password").toCharArray() ) ;
        }
    });
正确答案是:

Authenticator.setDefault(new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(
                    "DOMAIN\\user",
                    "password".toCharArray() ) ;
        }
    });

此问题已在JDK 9-ea中通过解决,并且修复程序也通过

将后端口传输到JDK 8u40。此错误的另一个可能原因是:域用户被阻止

Scheme:ntlm
Scheme:ntlm
java.net.ProtocolException: Server redirected too many  times (20)

在我不小心阻止了我的域用户之后,当我尝试使用超过域策略允许的错误密码登录时,我出现了相同的错误。

您使用的是什么java 7版本?我在使用https或身份验证或安全性时遇到一些问题。我开发的一个应用程序刚刚使用Java1.7_02(Java7.2),但当我使用最新版本时,它就不再工作了。Oracle在最新版本中做了一些修改,特别是在安全策略方面。尝试使用旧版本的java 7,如1.7_02。我刚刚使用java jdk 1.7.0_02 64位linux版进行了尝试,但没有成功,结果是相同的。另外,使用1.7.0_40-64位linux版进行了伪1.7.0_25-b15(64位)尝试,在linux上失败-在solaris上失败32位-在Windows 7上成功64位您是否向Oracle报告了此错误?错误报告:。仍然标记为打开。
Scheme:ntlm
Scheme:ntlm
java.net.ProtocolException: Server redirected too many  times (20)