代码之家  ›  专栏  ›  技术社区  ›  srinannapa

为什么不调用GetPasswordAuthentication()?

  •  2
  • srinannapa  · 技术社区  · 14 年前
    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已启用身份验证,但不确定它是哪种类型的身份验证。

    7 回复  |  直到 7 年前
        1
  •  5
  •   BalusC    14 年前

    这个 Authenticator 仅用于网站使用 basic HTTP authentication (您在其中看到著名的javascript样式登录/密码弹出窗口的网站),而不是使用 form based authentication (基于HTML <form> 登录名和密码字段通常为eyecandy标记/样式),也不像ISP的拨号登录。对于前者,实际上需要将登录名作为querystring传递,对于后者,实际上需要事先手动连接ISP或创建/使用代理。

        2
  •  2
  •   Arjan Tijms Mike Van    12 年前

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

    static {
        NTLMAuthenticationCallback.setNTLMAuthenticationCallback(new NTLMAuthenticationCallback()
        {
            @Override
            public boolean isTrustedSite(URL url)
            {
                return false;
            }
        });
    }  
    
        3
  •  0
  •   2red13    14 年前

    试试这个

        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;
    
        4
  •  0
  •   stevelo    8 年前

    也可能是服务器端需要先发制人的身份验证,并直接返回405错误响应。

    标准HTTP基本身份验证如下: 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

    对于先发制人身份验证: 1. client sends a request without authentication info. 2. server sends back 405, because there is no authentication info 因此不调用GetPasswordAuthentication()。

    这种情况的解决方法是编码用户名:密码并将其放在“授权”头中。(例如:授权:基本sldsfkjdsfjosdfjosjsdfs)

        5
  •  0
  •   drifterxy    7 年前

    我在12.1.1中遇到了这个问题,它使用的是默认的HTTP处理程序,而不是java.net.authenticator,可能有两个选项来处理这个问题:

    选项1,通过URL使用HTTP授权以避免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处理程序保持使用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处理程序配置为WebLogic12c,在我忘记使其正常工作的客户机或服务器中,或者在其中一个客户机或服务器中配置为WebLogic12c,因为在该服务器上运行的其他应用程序上可能存在风险,我不在此建议。

        6
  •  -2
  •   Jaydeep Patel    14 年前

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

    https://login.yahoo.com/config/login_verify2?&.src=ym
    
        7
  •  -3
  •   Scott    14 年前

    如果getPasswordAuthentication()是一个实际的方法,而不仅仅是您描述需要发生的事情,那么它实际上根本不是您的代码中的一行。我想你是想在这句话之后打电话给它:

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

    我看到它被宣布但从未打过电话。