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

-- What do i check now , getPasswordAuthentication is not at all being called ? I'm sure my IE is authentication enabled , but not sure what type of authentication was it.

srinannapa
  • 3,085
  • 8
  • 49
  • 66

8 Answers8

5

The Authenticator is only used for websites using basic HTTP authentication (websites wherein you see the well known Javascript-style login/password popup), not websites using form based authentication (a HTML based <form> with login and password fields in usually an eyecandy markup/style) and also not as dialup-like login for your ISP. For the former, you actually need to pass the login as querystring and for the latter, you actually need to manually connect the ISP beforehand or create/use a proxy.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • pls check the comments below the question – srinannapa Sep 21 '10 at 13:18
  • The authenticator is not to be used as entry password of your ISP. It's to be used for websites using basic HTTP authentication. That are two completely different things. You need a proxy here. – BalusC Sep 21 '10 at 13:19
  • If the server sends a HTTP 401, but no WWW-Authenticate header, then the Authenticator also will not be called. – mhaller Mar 13 '14 at 12:10
  • i get a HTTP 401 with WWW-Authenticate header value as NTLM. But still the Authenticator.getpasswordauthentication() is not being called. – Soorya Chandrasekaran Dec 16 '16 at 15:13
2

Sun.net.www.protocol.http.ntlm.NTLMAuthentication attempts to use transparent authentication, what is basically use of current user credentials to login to remote server. In my server to server scenario (Java EE server to Sharepoint) this wasn't acceptable. In order to disable transparent authentication we need to let authentication provider know that connection is not trusted and it needs to authenticate with every call:

static {
    NTLMAuthenticationCallback.setNTLMAuthenticationCallback(new NTLMAuthenticationCallback()
    {
        @Override
        public boolean isTrustedSite(URL url)
        {
            return false;
        }
    });
}  
Arjan Tijms
  • 37,782
  • 12
  • 108
  • 140
Boris R.
  • 371
  • 4
  • 11
1

It also could be the server side requires preemptive authentication and give back a 405 error response directly.

The standard http basic authentication is like: 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

For preemptive authentication: 1. client sends a request without authentication info. 2. server sends back 405, because there is no authentication info so getPasswordAuthentication() is not called.

The workaround for this situation is to encode username:password and put it in "Authorization" head. (e.g. Authorization: Basic sldsfkjdsfjosdfjosjsdfs)

stevelo
  • 114
  • 1
  • 2
0

Try this instead

    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;
2red13
  • 11,197
  • 8
  • 40
  • 52
0

I face this issue in 12.1.1 which use default http handler not works with the java.net.Authenticator, may have 2 options to deal with this:

option 1, use http Authorization over URL to avoid 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);

option 2, keep use java.net.Authenticator by config the http Handler

Authenticator.setDefault(new MyAuthenticator());

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

otherwise you may able to config the sun http handler to weblogic 12c in both or one of client or server I forgot to make it works, as it may risk on other applications run in this server I would not suggest here.

drifterxy
  • 1
  • 1
0

getPasswordAuthentication() is not called because Authenticator caches successful authentication attempts and uses the cache in future requests, unless you call Authenticator.setDefault(null) to remove it.

-2

Use url that ask for login. In your case you can change yahoo url to

https://login.yahoo.com/config/login_verify2?&.src=ym
Jaydeep Patel
  • 2,394
  • 1
  • 21
  • 27
-3

If getPasswordAuthentication() is an actual method and not just you wording what you need to happen, it's actually not currently a line in your code at all. I would assume you mean to call it after this line:

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

I see it being declared but never called.

Scott
  • 2,143
  • 2
  • 19
  • 25