为什么没有调用getPasswordAuthentication()?

时间:2010-09-21 13:02:49

标签: java

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.PasswordAuthentication;
import java.net.URL;

import sun.net.www.protocol.http.AuthCacheImpl;
import sun.net.www.protocol.http.AuthCacheValue;



public class RunHttpSpnego {
  public static void main(String args[]) throws MalformedURLException,
      IOException {
    String urlString = "http://www.yahoo.com";
    String username = "XXXXXXXXX";
    String password = "XXXXXXXX";
     // This is modified after the question is being asked. Now this code works fine
     System.setProperty("http.proxyHost","176.x.xx.xx") ;
    System.setProperty("http.proxyPort", "8080") ;

    Authenticator.setDefault(new MyAuthenticator(username, password));


    URL url = new URL(urlString);
    InputStream content = (InputStream) url.getContent();
    BufferedReader in = new BufferedReader(new InputStreamReader(content));
    String line;
    while ((line = in.readLine()) != null) {
      System.out.println(line);
    }
    System.out.println("Done.");
  }

  static class MyAuthenticator extends Authenticator {
    private String username, password;

    public MyAuthenticator(String user, String pass) {
      username = user;
      password = pass;
    }

    protected PasswordAuthentication getPasswordAuthentication() {
      System.out.println("Requesting Host  : " + getRequestingHost());
      System.out.println("Requesting Port  : " + getRequestingPort());
      System.out.println("Requesting Prompt : " + getRequestingPrompt());
      System.out.println("Requesting Protocol: "
          + getRequestingProtocol());
      System.out.println("Requesting Scheme : " + getRequestingScheme());
      System.out.println("Requesting Site  : " + getRequestingSite());
      return new PasswordAuthentication(username, password.toCharArray());
    }
  }
}

- 我现在检查什么,getPasswordAuthentication根本没有被调用?我确定我的IE启用了身份验证,但不确定它是什么类型的身份验证。

8 个答案:

答案 0 :(得分:5)

Authenticator仅用于使用basic HTTP authentication的网站(其中您看到众所周知的Javascript样式登录/密码弹出窗口的网站),而不是使用form based authentication的网站(基于HTML的{ {1}}登录名和密码字段通常是eyecandy标记/样式),也不是ISP的拨号式登录。对于前者,您实际上需要将登录作为查询字符串传递,对于后者,您实际上需要事先手动连接ISP或创建/使用代理。

答案 1 :(得分:2)

Sun.net.www.protocol.http.ntlm.NTLMAuthentication尝试使用透明身份验证,基本上使用当前用户凭据登录到远程服务器。在我的服务器到服务器场景(Java EE服务器到Sharepoint)中,这是不可接受的。为了禁用透明身份验证,我们需要让身份验证提供程序知道连接不受信任,并且需要对每次调用进行身份验证:

static {
    NTLMAuthenticationCallback.setNTLMAuthenticationCallback(new NTLMAuthenticationCallback()
    {
        @Override
        public boolean isTrustedSite(URL url)
        {
            return false;
        }
    });
}  

答案 2 :(得分:0)

试试这个

    DefaultHttpClient http = new DefaultHttpClient();
    final String username = "xxxx";
    final String password = "xxxx";
    UsernamePasswordCredentials c = new UsernamePasswordCredentials(username,password);
    BasicCredentialsProvider cP = new BasicCredentialsProvider(); 
    cP.setCredentials(AuthScope.ANY, c); 
    http.setCredentialsProvider(cP);

    HttpResponse res;

答案 3 :(得分:0)

服务器端也可能需要抢占式身份验证,并直接回复405错误响应。

标准的http基本身份验证如下: export PYTHONIOENCODING=utf-8

对于抢先身份验证: 1. client sends a request without authentication info. 2. server sends back 401 3. client resend the request with authentication info. 4. server send 200 所以不调用getPasswordAuthentication()。

此情况的解决方法是对用户名:密码进行编码并将其置于“授权”头中。 (例如授权:基本sldsfkjdsfjosdfjosjsdfs)

答案 4 :(得分:0)

我在12.1.1中遇到这个问题,使用默认的http处理程序不能与java.net.Authenticator一起使用,可能有2个选项来处理这个问题:

选项1,对URL使用http Authorization以避免使用java.net.Authenticator。

HttpURLConnection uc = null;
URL url = new URL(server_URL);
uc = (HttpURLConnection) url.openConnection();
String userPassword = myaccount + ":" + mypassword;
String encoding = new sun.misc.BASE64Encoder().encode(userPassword.getBytes());
uc.setRequestProperty("Authorization", "Basic " + encoding);

选项2,通过配置http Handler

继续使用java.net.Authenticator
Authenticator.setDefault(new MyAuthenticator());

URL url = new URL(null, service_URL, new sun.net.www.protocol.http.Handler());
uc = (HttpURLConnection) url.openConnection();

否则您可以将sun http处理程序配置为weblogic 12c中的两个或客户端或服务器中的一个我忘记使其正常工作,因为它可能会冒这个服务器上运行的其他应用程序的风险,我不会在这里建议。

答案 5 :(得分:0)

getPasswordAuthentication()不会被调用,因为Authenticator会缓存成功的身份验证尝试并在以后的请求中使用该缓存,除非您调用Authenticator.setDefault(null)来将其删除。

答案 6 :(得分:-2)

使用要求登录的网址。在您的情况下,您可以将雅虎网址更改为

https://login.yahoo.com/config/login_verify2?&.src=ym

答案 7 :(得分:-3)

如果getPasswordAuthentication()是一个实际的方法而不仅仅是你需要发生什么,那么它实际上根本不是代码中的一行。我认为你的意思是在这一行之后调用它:

Authenticator.setDefault(new MyAuthenticator(username, password));

我看到它被宣布但从未被召唤过。