forcedotcom / forcedotcom/wsc

JdkHttpTransport does not work with authenticated proxy

Open
#207 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
276
Forks
223
PR merge metrics
No merged PRs in 30d

Description

PartnerConnection on manual login with authenticated proxy throws 407 - Authentication required error. On quick prodding, the JdkHttpTransport is fuzzy around here:
```
if (config.getProxyUsername() != null) {
String token = config.getProxyUsername() + ":" + config.getProxyPassword();
String auth = "Basic " + new String(Base64.encode(token.getBytes()));
connection.addRequestProperty("Proxy-Authorization", auth);
connection.addRequestProperty("Https-Proxy-Authorization", auth);
}
```
The debug adds the request property but the request submitted does not contain the headers for authentication. This is the root cause for the proxy with authentication issue. Strangely, the issue does not appear with data loader and upon analysis, I could find out that dataloader uses [HttpClientTransport ](https://github.com/forcedotcom/dataloader/blob/5fd2ef7316da4cb137ded6fe81d708ac156ec408/src/main/java/com/salesforce/dataloader/client/HttpClientTransport.java) for proxy with authentication. Unless this change is incorporated on wsc, the proxy with authentication as well as NTLM auth will not work.

To reproduce:
```
String proxyUsername = "";
String proxyPassword = "";
String username = "";
String password = "";
String endpoint = "https://test.salesforce.com/services/Soap/u/37.0";
String proxyHost = "";
int proxyPort = 0;

System.setProperty("http.proxyHost", proxyHost);
System.setProperty("http.proxyPort", Integer.toString(proxyPort));
System.setProperty("https.proxyHost", proxyHost);
System.setProperty("https.proxyPort", Integer.toString(proxyPort));
Authenticator.setDefault(new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(proxyUsername, proxyPassword.toCharArray());
}
});
ConnectorConfig partnerConfig = new ConnectorConfig();
partnerConfig.setUsername(username);
partnerConfig.setPassword(password);
partnerConfig.setAuthEndpoint(endpoint);
partnerConfig.setProxy(proxyHost, proxyPort);
partnerConfig.setProxyUsername(proxyUsername);
partnerConfig.setProxyPassword(proxyPassword);
PartnerConnection partner = new PartnerConnection(partnerConfig);
```

Finally, to resolve this, add the line if using proxy with auth/NTLM auth:
`partnerConfig.setTransport(HttpClientTransport.class);`

Additionally, the BulkConnection is not equipped with proxy authentication.
```
private InputStream doHttpGet(URL url) throws IOException, AsyncApiException {
**HttpURLConnection connection = config.createConnection(url, null);**
connection.setRequestProperty(SESSION_ID, config.getSessionId());

boolean success = true;
InputStream in;
try {
in = connection.getInputStream();
} catch (IOException e) {
success = false;
in = connection.getErrorStream();
}
```
Additional headers might be required while creating connection here. It throws 407 unauthenticated here.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by comparing JdkHttpTransport with the referenced HttpClientTransport, then trace ConnectorConfig.createConnection and BulkConnection.doHttpGet. Reproduce the 407 response with an authenticated proxy and verify that PartnerConnection and BulkConnection complete requests through the proxy without unauthenticated failures.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
api, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.