Jax-RS unable to authenticate to proxy

2.3k views Asked by At

My company has a proxy

proxy=myProxy
port=myProxyPort
username=me
password=myPassword

I try to access the outside world by using simple java.net functions and it worked!

System.setProperty("http.proxyHost", myProxy);
System.setProperty("http.proxyPort", myProxyPort);

Authenticator.setDefault(new Authenticator() {
      protected PasswordAuthentication getPasswordAuthentication() {
        return new
           PasswordAuthentication(me,myPasssword.toCharArray());
    }});

URL u = new URL("http://www.google.com");
HttpURLConnection con = (HttpURLConnection) u.openConnection();
DataInputStream di = new DataInputStream(con.getInputStream());
byte[] b = new byte[1024*512];
while(-1 != di.read(b,0,1024*512)) {
   System.out.print(new String(b));

Not I try to do it by using Jax-RS Resteasy Implementation like that:

Client client = new ResteasyClientBuilder().defaultProxy(myProxy, myProxyPort).build(); 
System.out.println(client.target("https://www.google.com").request().get().readEntity(String.class));

I got the following error

Cache Access Denied
ERR_CACHE_ACCESS_DENIED
(squid/3.1.6)
Sorry, you are not currently allowed to request https://www.google.com/* from this cache until you have authenticated yourself

Can somebody tell me how to authenticate to the proxy with username-password using Jax-RS

3

There are 3 answers

0
Oscar Castiblanco On BEST ANSWER

Wow, It really make me crazy this problem. I don't know how to solve it in an implementation independent way. Anyway, by now it worked like that:

ResteasyClient client = new ResteasyClientBuilder().defaultProxy(myProxy, myProxyPort).build(); 
Credentials credentials = new UsernamePasswordCredentials(me, mypassword);
ApacheHttpClient4Engine engine = (ApacheHttpClient4Engine)client.httpEngine();
HttpContext context =  new BasicHttpContext();
engine.setHttpContext(context);

CredentialsProvider provider = new BasicCredentialsProvider(); 
context.setAttribute(ClientContext.CREDS_PROVIDER, provider);
AuthScope authScope = new AuthScope(
            myProxy,
            myProxyPort,
            null,
            null);
System.out.println(client.target("https://www.google.com").request().get().readEntity(String.class));
0
Thierry On

The simplest approach is not to use the default underlying Apache engine but to set the standard Java URLConnection instead:

resteasyClientBuilder.httpEngine(new URLConnectionEngine());
client = resteasyClientBuilder.build();

If so, all the http.proxyXXX system properties will work avoiding coding any credentials provider.

0
Jason Huntley On

I encountered this same issue while extending Keycloak(17) for our services. The Quarkus reactive rest library, released with this version of keycloak, didn't quite provide what we needed to authenticate through a proxy. We had to work around the issue using Apache's HTTP Client library, httpclient:4.5.13, directly. For those interested, here's another work around:

Credentials credentials = new UsernamePasswordCredentials(proxyUser, proxyPassword);
CredentialsProvider credProvider = new BasicCredentialsProvider();
credProvider.setCredentials(new AuthScope(proxyHost, Integer.parseInt(proxyPort)), credentials);

//
// Important notes to be aware of when using RestEasy api in keycloak/quarkus
// https://github.com/quarkusio/quarkus/issues/22466
//

HttpClientBuilder clientbuilder = HttpClients.custom();

clientbuilder = clientbuilder.setDefaultCredentialsProvider(credProvider);
this.httpclient = clientbuilder.build();

HttpHost proxy = new HttpHost(proxyHost, Integer.parseInt(proxyPort));

RequestConfig.Builder reqconfigconbuilder= RequestConfig.custom();
reqconfigconbuilder = reqconfigconbuilder.setProxy(proxy);
RequestConfig config = reqconfigconbuilder.build();

String encoding = Base64.getEncoder().encodeToString((emailUser + ":" + emailPassword).getBytes());

this.target = new HttpHost(emailServer, Integer.parseInt(emailPort), "https");
this.postRequest = new HttpPost("/resource/example");
this.postRequest.setConfig(config);
this.postRequest.addHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoding);
this.postRequest.addHeader("content-type", "application/json");