"407 Proxy Authentication Required" error during java rest request occationally

I am trying to perform a REST request to one of my client URL to get the response using proxy.Most of the time i am able to get the response using my code.But sometimes when i try to send a request using my code i am receiving "407 Proxy Authentication Required" error.This happens rarely but once i get this error,for every consecutive requests i am getting the same error.But when i use POSTMAN tool from chrome to send the same request that was generated to the same URL ,I will be getting the response.But as soon as i get response from POSTMAN if i try with my code again i start getting the response not only from my local machine but from different machines where i run the code as well.I am very confused regarding the issue and not able to figure out why this strange scenario occurs.Is there something i am missing in my code.Kindly help me out guys.I have given my code below :

Code

public Map<String ,Object> ConnectRestService(MyRequest myRequest, String postURL, String httpProxy,int timeout int httpPort, Map<String ,Object> responseMap)
        throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, CustomException{

    MyResponse myResponse = new MyResponse();
    Map<String ,Object> responseReturnMap = new HashMap<>();
    String output = "";
    TrustStrategy acceptingTrustStrategy = new TrustStrategy() {

        @Override
        public boolean isTrusted(java.security.cert.X509Certificate[] chain, String authType)
                throws java.security.cert.CertificateException {
            // TODO Auto-generated method stub
            return true;
        }
    };

    SSLContext sslContext = SSLContexts.custom()
            .loadTrustMaterial(null, acceptingTrustStrategy)
            .build();


    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    HttpClient httpClient;
    httpClient = HttpClients.custom().setSSLSocketFactory(csf).setProxy(new HttpHost(httpProxy, httpPort)).build();

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.add("Content-type", "text/xml");
    httpHeaders.add("Accept", "text/xml");
    httpHeaders.add("access-control-allow-origin", "*");
    httpHeaders.add("content-encoding", "UTF-8");
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
    requestFactory.setConnectTimeout(timeout);


    try {
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        HttpEntity<MyRequest> entity = new org.springframework.http.HttpEntity<MyRequest>(
                myRequest, httpHeaders);
        ResponseEntity<String> response = restTemplate.exchange(postURL, HttpMethod.POST, entity, String.class);


    } catch (Exception ex) {
        logger.error(ex.getMessage(), ex);
    }

    return responseReturnMap;
}

Kindly help me out figuring out what i am missing here.

Upvotes: 3

Views: 25061

Answers (6)

Chetan Punjabi
Chetan Punjabi

Reputation: 1

In my case, I had some proxy defined in the settings.xml file at \netbeans\java\maven\conf like :

<proxy>
    <id>netbeans-default-proxy</id>
    <active>true</active>
    <protocol>http</protocol>
    <host>******************</host>
    <port>****</port>
</proxy>

which was causing this. Once I removed it, relaunched NetBeans and tried to do a Clean and Build of the project and it worked like a charm.

Upvotes: 0

Lubo
Lubo

Reputation: 1837

Please try to clean-up your code a bit. I think that creating RestTemplate each time creating pressure to garbage collector, but can also lead to other problems. Also you are returning always empty map from your method (probably cleaning code during debugging...).

To address your problem, please try to check your tcp stack, or tcp stack of proxy server (if any) when problem arises. For example have a look at number of opened connections with command like this:

ss -s

PS: Restarting your client app/server does help also? Are there any other possibilities how to "make it work again", instead of using postman?

Upvotes: 0

Anish B.
Anish B.

Reputation: 16539

I think you are trying to access it from a proxy server. In that case, you have to add Proxy-Authorization in the header.

Try with this code snippet:

String data = "user:password"; // Here proxy user and password to be used.
String encodedValue = Base64.getEncoder().encodeToString(data.getBytes());
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Proxy-Authorization", "Basic " + encodedValue); // You need to add proxy-authorization in the header.

Read this link : Mozilla documentation for Proxy-Authorization

Upvotes: 0

Sid
Sid

Reputation: 349

Looking at your code, I became interested in this line of code :

httpHeaders.add("access-control-allow-origin", "*");

Instead of using an asterisk, you could try specifying the origin of the source, i.e. from where the request is to emanate. Browsers like chrome or firefox may not always behave correctly afaik when it sees an origin missing MAYBE due to domains being different or due to CORS issues.

When the request is sent, the network layer tries to look for the resource and here it seems the non-simple header is causing an issue or confusing the browser. The browser first sends a data-less OPTIONS request [an underlying first action for requests to see what is to be served and if found true, proceed with the real request], to confirm that the server will accept the request for a suitable response.

I think that the Content-Type not being any of the following like - application/x-www-form-urlencoded, multipart/form-data, or text/plain makes the request be non-simple. More on this here for non-simple requests.

Also, it would be good to check if your java program is sending the Proxy-Authorization header. Check the TCP session headers to see if it's missing.

Another part that I may want to test is with a proxied rest template. Of course, you may need it to be modified as required to work with SSL but below is a basic sample with authentication credentials.

 private final RestTemplate getProxiedRestTemplate() {
    RestTemplate r = null;
    if (isProxyActivated()) {
        HttpClientBuilder client = HttpClientBuilder.create();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        client.setProxy(new HttpHost("your ip", 8080 //or the port you want to use}
));
        if (withAuthentication()) {
            Credentials credentials = new UsernamePasswordCredentials(getProxyUsername(), getProxyPassword());
            AuthScope authScope = new AuthScope("your ip", 8080);
            CredentialsProvider credsProvider = new BasicCredentialsProvider();
            credsProvider.setCredentials(authScope, credentials);
            client.setDefaultCredentialsProvider(credsProvider);
        }
        requestFactory.setHttpClient(client.build());
        r = new RestTemplate(requestFactory);
    } else {
        r = new RestTemplate();
    }
    return r;
}

I hope the post is helpful or at least drives you in a more suitable direction, all the best.

Upvotes: 0

Pranjal Gore
Pranjal Gore

Reputation: 592

In case of a 407 error, the response that you are receiving must contain a special Proxy-Authenticate header. This header will tell you what kind of authentication the proxy server is expecting.

What you need to do is include a Proxy-Authorization header in your request. The typical syntax for a Proxy-Authorization header is Proxy-Authorization:<type-of-authentication-scheme> <credentials-for-authentication-at-proxy-server>.

Proxy-Authenticate header will let you know the type of authentication scheme that you need to use.

Upvotes: 6

Siva
Siva

Reputation: 768

From what I've observed, some softwares simply show a popup asking for credentials in such cases. Many times this window goes 'behind' the current window you are working, and you never even notice that the credentials have been asked for. So, in many cases, you as a humanbeing are not even keying in the credentials as (unfortunately) the popup is shown 'behind' the current working window.

So, next time you face such an issue, quickly check if there are any native popups that have shown up behind the scenes and key in your credentials there quickly.

Now, one more thing that I've seen is that certain command line tools (example git etc.) when connecting to a URL again will have to go through the proxy and those tools sometimes do a lousy job of credential management. For this, one more way is 'credential manager' that is given in Windows. Just go there, and 'add' the URL in credential manager and key in the credentials there, and close all your commandline windows and retry what you were trying. This time things should just work fine.

There are 'flavours' of credentials, one with 'Domain name' (usually if you are behind a corporate proxy).

Example: Your Windows login ID in a corporate network can be just 'Deepak', or it can be DOMAINNAME\Deepak so try them both as user name in 'windows credential manager'

Try these, and all the best.

https://support.microsoft.com/en-us/help/4026814/windows-accessing-credential-manager

Upvotes: 0

Related Questions