[ 
https://issues.apache.org/jira/browse/HTTPCLIENT-1457?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Mat Gessel updated HTTPCLIENT-1457:
-----------------------------------

    Description: 
I ran into this with NTLM proxy authentication. 

Summary: 
HttpClientBuilder.useSystemProperties() results in 
SystemDefaultCredentialsProvider being specified. 
SystemDefaultCredentialsProvider delegates authentication to 
java.net.Authenticator and always returns credentials as 
UsernamePasswordCredentials. NTLMScheme expects credentials to be an instance 
of NTCredentials.

Note: This works in "plain old Java". That is: URL connections work through an 
NTLM authenticating proxy if the default java.net.Authenticator is set. 

NTLMScheme casts provided credentials to NTCredentials, generating an 
exception. The end result (for proxy auth) is a HTTP 407 status and the 
following log message: 

WARN org.apache.http.impl.auth.HttpAuthenticator - NTLM authentication error: 
Credentials cannot be used for NTLM authentication: 
org.apache.http.auth.UsernamePasswordCredentials

Nitpick: NTLMScheme.authenticate() should guard the argument with an  
"instanceof" instead of catching a ClassCastException. 

The code boils down to this: 
java.net.Authenticator.setDefault(new Authenticator()
{
    @Override
    protected PasswordAuthentication getPasswordAuthentication()
    {
        if (getRequestorType() == RequestorType.PROXY)
        {
            String prot = getRequestingProtocol().toLowerCase();
            String host = System.getProperty(prot + ".proxyHost", "");
            String port = System.getProperty(prot + ".proxyPort", "80");
            String user = System.getProperty(prot + ".proxyUser", "");
            String password = System.getProperty(prot + ".proxyPassword", "");

            if (getRequestingHost().equalsIgnoreCase(host))
            {
                if (port != null && 
port.equals(Integer.toString(getRequestingPort())))
                {
                    return new PasswordAuthentication(user, 
password.toCharArray());
                }
            }
        }
        return null;
    }
});


HttpClients.custom().useSystemProperties().build().execute(new 
HttpGet("http://example.com";));

Workaround
===============
This following works in my initial tests: 
class SystemDefaultCredentialsProviderFixed extends 
SystemDefaultCredentialsProvider
{
  @Override
  public Credentials getCredentials(AuthScope authscope)
  {
    Credentials credentials = super.getCredentials(authscope);
    if (credentials != null && "NTLM".equals(authscope.getScheme()))
    {
      String domain = System.getProperty("http.auth.ntlm.domain");
      credentials = new NTCredentials(credentials.getUserPrincipal().getName(), 
credentials.getPassword(), null, domain);
    }
    return credentials;
  }
}

HttpClients.custom().useSystemProperties().setDefaultCredentialsProvider(SystemDefaultCredentialsProviderFixed).build().execute(new
 HttpGet("http://example.com";));

  was:
I ran into this with NTLM proxy authentication. 

Summary: 
HttpClientBuilder.useSystemProperties() results in 
SystemDefaultCredentialsProvider being specified. 
SystemDefaultCredentialsProvider delegates authentication to 
java.net.Authenticator and always returns credentials as 
UsernamePasswordCredentials. NTLMScheme expects credentials to be an instance 
of NTCredentials.

Note: This works in "plain old Java". That is: URL connections work through an 
NTLM authenticating proxy if the default java.net.Authenticator is set. 

NTLMScheme casts provided credentials to NTCredentials, generating an 
exception. The end result (for proxy auth) is a HTTP 407 status and the 
following log message: 

WARN org.apache.http.impl.auth.HttpAuthenticator - NTLM authentication error: 
Credentials cannot be used for NTLM authentication: 
org.apache.http.auth.UsernamePasswordCredentials

Nitpick: NTLMScheme.authenticate() should guard the argument with an  
"instanceof" instead of catching a ClassCastException. 

The code boils down to this: 
java.net.Authenticator.setDefault(new Authenticator()
{
    @Override
    protected PasswordAuthentication getPasswordAuthentication()
    {
        if (getRequestorType() == RequestorType.PROXY)
        {
            String prot = getRequestingProtocol().toLowerCase();
            String host = System.getProperty(prot + ".proxyHost", "");
            String port = System.getProperty(prot + ".proxyPort", "80");
            String user = System.getProperty(prot + ".proxyUser", "");
            String password = System.getProperty(prot + ".proxyPassword", "");

            if (getRequestingHost().equalsIgnoreCase(host))
            {
                if (port != null && 
port.equals(Integer.toString(getRequestingPort())))
                {
                    return new PasswordAuthentication(user, 
password.toCharArray());
                }
            }
        }
        return null;
    }
});


HttpClients.custom().useSystemProperties().build().execute(new 
HttpGet("http://example.com";));


> HttpClientBuilder.useSystemProperties() is incompatible with NTLM scheme
> ------------------------------------------------------------------------
>
>                 Key: HTTPCLIENT-1457
>                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-1457
>             Project: HttpComponents HttpClient
>          Issue Type: Bug
>          Components: HttpAuth, HttpClient
>    Affects Versions: 4.3.2
>         Environment: Client: JRE 5 - JRE 7
> Proxy: Squid with Winbind & NTLM authentication
> Auth server: Windows server 2003 / 2008
>            Reporter: Mat Gessel
>
> I ran into this with NTLM proxy authentication. 
> Summary: 
> HttpClientBuilder.useSystemProperties() results in 
> SystemDefaultCredentialsProvider being specified. 
> SystemDefaultCredentialsProvider delegates authentication to 
> java.net.Authenticator and always returns credentials as 
> UsernamePasswordCredentials. NTLMScheme expects credentials to be an instance 
> of NTCredentials.
> Note: This works in "plain old Java". That is: URL connections work through 
> an NTLM authenticating proxy if the default java.net.Authenticator is set. 
> NTLMScheme casts provided credentials to NTCredentials, generating an 
> exception. The end result (for proxy auth) is a HTTP 407 status and the 
> following log message: 
> WARN org.apache.http.impl.auth.HttpAuthenticator - NTLM authentication error: 
> Credentials cannot be used for NTLM authentication: 
> org.apache.http.auth.UsernamePasswordCredentials
> Nitpick: NTLMScheme.authenticate() should guard the argument with an  
> "instanceof" instead of catching a ClassCastException. 
> The code boils down to this: 
> java.net.Authenticator.setDefault(new Authenticator()
> {
>     @Override
>     protected PasswordAuthentication getPasswordAuthentication()
>     {
>         if (getRequestorType() == RequestorType.PROXY)
>         {
>             String prot = getRequestingProtocol().toLowerCase();
>             String host = System.getProperty(prot + ".proxyHost", "");
>             String port = System.getProperty(prot + ".proxyPort", "80");
>             String user = System.getProperty(prot + ".proxyUser", "");
>             String password = System.getProperty(prot + ".proxyPassword", "");
>             if (getRequestingHost().equalsIgnoreCase(host))
>             {
>                 if (port != null && 
> port.equals(Integer.toString(getRequestingPort())))
>                 {
>                     return new PasswordAuthentication(user, 
> password.toCharArray());
>                 }
>             }
>         }
>         return null;
>     }
> });
> HttpClients.custom().useSystemProperties().build().execute(new 
> HttpGet("http://example.com";));
> Workaround
> ===============
> This following works in my initial tests: 
> class SystemDefaultCredentialsProviderFixed extends 
> SystemDefaultCredentialsProvider
> {
>   @Override
>   public Credentials getCredentials(AuthScope authscope)
>   {
>     Credentials credentials = super.getCredentials(authscope);
>     if (credentials != null && "NTLM".equals(authscope.getScheme()))
>     {
>       String domain = System.getProperty("http.auth.ntlm.domain");
>       credentials = new 
> NTCredentials(credentials.getUserPrincipal().getName(), 
> credentials.getPassword(), null, domain);
>     }
>     return credentials;
>   }
> }
> HttpClients.custom().useSystemProperties().setDefaultCredentialsProvider(SystemDefaultCredentialsProviderFixed).build().execute(new
>  HttpGet("http://example.com";));



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to