使用 java 从 Internet 下载文件:如何进行身份验证?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/955624/
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-08-11 21:33:32  来源:igfitidea点击:

Download a file from the internet using java : How to authenticate?

javaauthenticationhttpwebrequestdownloadbasic-authentication

提问by user105413

Thanks to this thread How to download and save a file from Internet using Java?I know how to download a file, now my problem is that I need to authenticate on the sever from which I'm dowloading. It's an http interface to a subversion server. Which field do I need to look up into ?

感谢这个线程如何使用 Java 从 Internet 下载和保存文件?我知道如何下载文件,现在我的问题是我需要在我下载的服务器上进行身份验证。它是一个到 Subversion 服务器的 http 接口。我需要查看哪个领域?

Using the code posted in the last comment, I get this exception:

使用最后一条评论中发布的代码,我得到了这个异常:

java.io.IOException: Server returned HTTP response code: 401 for URL: http://myserver/systemc-2.0.1.tgz
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1305)
    at java.net.URL.openStream(URL.java:1009)
    at mypackage.Installer.installSystemc201(Installer.java:29)
    at mypackage.Installer.main(Installer.java:38)

Thanks,

谢谢,

采纳答案by Yishai

You extend the Authenticatorclass and register it. The javadocs at the link explain how.

您扩展Authenticator类并注册它。链接中的 javadocs 解释了如何。

I don't know if this works with the nio method that got the accepted answer to the question, but it for sure works for the old fashioned way that was the answer under that one.

我不知道这是否适用于得到问题的公认答案的 nio 方法,但它肯定适用于老式方法,即该方法下的答案。

Within the authenticator class implementation, you are probably going to use a PasswordAuthenticationand override the getPasswordAuthentication() method of your Authenticator implementation to return it. That will be the class which is passed the user name and password you need.

在身份验证器类实现中,您可能会使用PasswordAuthentication并覆盖 Authenticator 实现的 getPasswordAuthentication() 方法以返回它。这将是传递您需要的用户名和密码的类。

Per your request, here is some sample code:

根据您的要求,以下是一些示例代码:

public static final String USERNAME_KEY = "username";
public static final String PASSWORD_KEY = "password";
private final PasswordAuthentication authentication;

public MyAuthenticator(Properties properties) {
    String userName = properties.getProperty(USERNAME_KEY);
    String password = properties.getProperty(PASSWORD_KEY);
    if (userName == null || password == null) {
        authentication = null;
    } else {
        authentication = new PasswordAuthentication(userName, password.toCharArray());
    }
}

protected PasswordAuthentication getPasswordAuthentication() {
    return authentication;
}

And you register it in the main method (or somewhere along the line before you call the URL):

然后在 main 方法中注册它(或在调用 URL 之前的某个地方):

Authenticator.setDefault(new MyAuthenticator(properties));

The usage is simple, but I find the API convoluted and kind of backwards for how you typically think about these things. Pretty typical of singleton design.

用法很简单,但我发现 API 令人费解,并且与您通常对这些事情的看法有些倒退。非常典型的单例设计。

回答by cmsjr

Have you tried building your URL in the form http://user:password@domain/path?

您是否尝试过以http://user:password@domain/path的形式构建您的 URL ?

回答by Chris Gow

I would suggest checking out HttpClient from apache http://hc.apache.org/httpclient-3.x/it makes downloading/authenticating very easy

我建议从 apache http://hc.apache.org/httpclient-3.x/查看 HttpClient它使下载/身份验证非常容易

回答by poundifdef

This is some code I wrote that fetches a website and displays the contents to System.out. It uses Basic authentication:

这是我编写的一些代码,用于获取网站并将内容显示到 System.out。它使用基本身份验证:

import java.net.*;
import java.io.*;

public class foo {
    public static void main(String[] args) throws Exception {

   URL yahoo = new URL("http://www.MY_URL.com");

   String passwdstring = "USERNAME:PASSWORD";
   String encoding = new 
          sun.misc.BASE64Encoder().encode(passwdstring.getBytes());

   URLConnection uc = yahoo.openConnection();
   uc.setRequestProperty("Authorization", "Basic " + encoding);

   InputStream content = (InputStream)uc.getInputStream();
   BufferedReader in   =   
            new BufferedReader (new InputStreamReader (content));

   String line;
   while ((line = in.readLine()) != null) {
      System.out.println (line);
   }   

   in.close();
}

Problems with the above code:

上面代码的问题:

  1. This code isn't production-ready (but it gets the point across.)

  2. The code yields this compiler warning:

  1. 这段代码不是生产就绪的(但它明白了这一点。)

  2. 该代码产生此编译器警告:

foo.java:11: warning: sun.misc.BASE64Encoder is Sun proprietary API and may be removed in a future release
      sun.misc.BASE64Encoder().encode(passwdstring.getBytes());
              ^ 1 warning

One really should use the Authenticator class, but for the life of me, I could not figure out how and I couldn't find any examples either, which just goes to show that the Java people don't actually like it when you use their language to do cool things. :-P

一个人真的应该使用 Authenticator 类,但在我的生活中,我无法弄清楚如何并且我也找不到任何示例,这只是表明 Java 人实际上并不喜欢使用他们的语言做很酷的事情。:-P

So the above isn't a goodsolution, but it does work and could easily be modified later.

所以以上不是一个好的解决方案,但它确实有效并且以后可以很容易地修改。

回答by Pat Gonzalez

This open source library, http://spnego.sourceforge.net, also has some examples on how to use it's SpnegoHttpURLConnection class.

这个开源库http://spnego.sourceforge.net也有一些关于如何使用它的 SpnegoHttpURLConnection 类的示例。

One of the constructors in the class allows you to pass-in a username and password.

类中的构造函数之一允许您传入用户名和密码。

Take a look at the class's java doc for the examples.

查看该类的 Java 文档以获取示例。

回答by Kairan

Write your overriding class for Authenticator:

为 Authenticator 编写覆盖类:

import java.net.Authenticator;
import java.net.PasswordAuthentication;

public class MyAuthenticator extends Authenticator {  
    private static String username = "";
    private static String password = "";

    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication (MyAuthenticator.username, 
                MyAuthenticator.password.toCharArray());
    }

    public static void setPasswordAuthentication(String username, String password) {
        MyAuthenticator.username = username;
        MyAuthenticator.password = password;
    }
}

Write your main class:

编写你的主类:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.URL;

public class MyMain{


    public static void main(String[] args) {
        URL url;
        InputStream is = null;
        BufferedReader br;
        String line;

        // Install Authenticator
        MyAuthenticator.setPasswordAuthentication("Username", "Password");
        Authenticator.setDefault (new MyAuthenticator ());

        try {
            url = new URL("Your_URL_Here");
            is = url.openStream();  // throws an IOException
            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (MalformedURLException mue) {
             mue.printStackTrace();
        } catch (IOException ioe) {
             ioe.printStackTrace();
        } finally {
            try {
                if (is != null) is.close();
            } catch (IOException ioe) {
                // nothing to see here
            }
        }

    }

}