I have WSDL. I need to make HTTP basic (preemptive) authentication.
What to do?
I tried :
Authenticator myAuth = new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("user", "pass".toCharArray());
}
};
Authenticator.setDefault(myAuth);
But it does not work: Caused by:
java.io.IOException: Server returned HTTP response code: 401 for URL ..
P.S. I use Apache CXF 2.6.2 and JBoss 5.0.1
What you specified for your authentication is not enough. You should do something like this:
private YourService proxy;
public YourServiceWrapper() {
try {
final String username = "username";
final String password = "password";
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
username,
password.toCharArray());
}
});
URL url = new URL("http://yourserviceurl/YourService?WSDL");
QName qname = new QName("http://targetnamespace/of/your/wsdl", "YourServiceNameInWsdl");
Service service = Service.create(url, qname);
proxy = service.getPort(YourService.class);
Map<String, Object> requestContext = ((BindingProvider) proxy).getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url.toString());
requestContext.put(BindingProvider.USERNAME_PROPERTY, username);
requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);
Map<String, List<String>> headers = new HashMap<String, List<String>>();
requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
} catch (Exception e) {
LOGGER.error("Error occurred in web service client initialization", e);
}
}
Properties:
YourService - your generated web service client interface.
YourServiceWrapper() - wrapper class constructor which initializes your service.
url - URL to your web service with ?WSDL extension.
qname - first constructor argument: target namespace from your WSDL file. Second: your service name from WSDL.
Then you will be able to call your web service methods like this:
proxy.whatEverMethod();
Related
I'm trying to use JDK 11 HttpClient to make requests through a corporate proxy which requires authentication by login and password. According to JDK's intro, I'm building an instance of client by means of:
HttpClient httpClient = HttpClient.newBuilder()
.version(HTTP_1_1)
.proxy(ProxySelector.of(new InetSocketAddress("proxy.mycompany.com", 3128)))
.authenticator(authenticator)
.build();
, where authenticator is:
Authenticator authenticator = new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("login", "password".toCharArray());
}
};
And then I execute the request itself:
HttpRequest outRequest = HttpRequest.newBuilder()
.version(HTTP_1_1)
.GET()
.uri(URI.create("https://httpwg.org/asset/http.svg")) // no matter which URI to request
.build();
HttpResponse<String> inResponse = httpClient.send(outRequest, BodyHandlers.ofString());
But instead of valid response from the target server (https://httpwg.org) I receive HTTP 407 (Proxy Authentication Required), i.e. HttpClient does not use the provided authenticator.
I've tried various solutions mentioned here and here but none of them helped.
What is the correct way to make it work?
You have to set the "Proxy-Authorization" header on the request.
HttpClient httpClient = HttpClient.newBuilder()
.version(HTTP_1_1)
.proxy(ProxySelector.of(new InetSocketAddress("proxy.mycompany.com", 3128)))
.build();
String encoded = new String(Base64.getEncoder().encode("login:password".getBytes()));
HttpRequest outRequest = HttpRequest.newBuilder()
.version(HTTP_1_1)
.GET()
.uri(URI.create("https://httpwg.org/asset/http.svg")) // no matter which URI to request
.setHeader("Proxy-Authorization", "Basic " + encoded)
.build();
By default, basic authentication with the proxy is disabled when tunneling through an authenticating proxy since java 8u111.
You can re-enable it by specifying -Djdk.http.auth.tunneling.disabledSchemes="" on the java command line.
See the jdk 8u111 release notes
Use
System.setProperty("jdk.http.auth.proxying.disabledSchemes", "");
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
Construct your http client with proxy selector and authenticator
HttpClient client = HttpClient.newBuilder()
.authenticator(yourCustomAuthenticator)
.proxy(yourCustomProxySelector)
.build();
In your Authenticator override
#Override
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestorType().equals(RequestorType.PROXY)) {
return getPasswordAuthentication(getRequestingHost());
} else {
return null;
}
}
protected PasswordAuthentication getPasswordAuthentication(String proxyHost) {
// your logic to find username and password for proxyHost
return new PasswordAuthentication(proxyUsername, proxyPassword.toCharArray());
// or return null
}
I am sending my credentials using,
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("username", "password".toCharArray());
}
});
My question is now how can I retrieve this credentials in Soap webservice Java?
Got solution,
ArrayList<String> authList = (ArrayList<String>) http_headers.get("Authorization");
It returns Credentials in Base64.
How can I use Socks5 proxy in Okhttp to start http request ?
My code:
Proxy proxy = new Proxy(Proxy.Type.SOCKS, InetSocketAddress.createUnresolved(
"socks5host", 80));
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy).authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
if (HttpUtils.responseCount(response) >= 3) {
return null;
}
String credential = Credentials.basic("user", "psw");
if (credential.equals(response.request().header("Authorization"))) {
return null; // If we already failed with these credentials, don't retry.
}
return response.request().newBuilder().header("Authorization", credential).build();
}
}).build();
Request request = new Request.Builder().url("http://google.com").get().build();
Response response = client.newCall(request).execute(); <--- **Here, always throw java.net.UnknownHostException: Host is unresolved: google.com**
System.out.println(response.body().string());
How to avoid UnknownHostException?
Any example ?
Thanks!
I found a solution: When create a OkHttpClient.Builder(), set a new socketFactory instead of set proxy, and return a sock5 proxy inside socketFactory createSocket.
I think it's the easiest working soulution. But it seems to me that it can be not 100% safe. I took this code from this code from here and modified it because my proxy's RequestorType is SERVER.
Actually, java has a strange api for proxies, you should to set auth for proxy through system env ( you can see it from the same link)
final int proxyPort = 1080; //your proxy port
final String proxyHost = "your proxy host";
final String username = "proxy username";
final String password = "proxy password";
InetSocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddr);
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
if (getRequestingHost().equalsIgnoreCase(proxyHost)) {
if (proxyPort == getRequestingPort()) {
return new PasswordAuthentication(username, password.toCharArray());
}
}
return null;
}
});
OkHttpClient client = new OkHttpClient.Builder()
.proxy(proxy)
.build();
I want to create my DbxRequestConfig Object with a StandardHttpRequestor, because I need it to use a Proxy.
The Proxy is a http Proxy, Port 80, and needs authentication.
Proxyaddress: http://myproxy.com
Proxyport: 80
Proxyusername: username
Proxypassword: password
So I tried to use the global Java Proxy setup:
System.setProperty("http.proxy","proxyaddress") //... http.proxyUser, http.ProxyPassword
//and so on
It did not work.
After looking into the StandardHttpRequestor I realized I need to use this Object as well as a Proyx Object:
Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(ip,port));
StandardHttpRequestor requ = new StandardHttpRequestor(proxy);
Which is wrong, because it has no authentication.
For authentication, the net and google show me the following. Putting all together, my current code looks like the following:
String ip = "http://myproxy.com";
int port = 80;
final String authUser = "username";
final String authPassword = "password";
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(authUser, authPassword.toCharArray());
}
});
System.setProperty("http.proxyUser", authUser);
System.setProperty("http.proxyPassword", authPassword);
Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(ip,port));
StandardHttpRequestor requ = new StandardHttpRequestor(proxy);
return requ;
But this does not work as well.
What am I doing wrong?
I can't seem to get the Proxy to work.
One problem was the http:// in String ip = "http://myproxy.com";
My current code looks the following, and works sometimes. Sometimes not. I have no idea why. Sometimes I have to reallow the App to be connected to my DropBox Account, because the authKey doesn't come through the proxy...
Well at least I got an example working for you guys having the same trouble. Maybe the rest of the problem is on the proxy side? I'll have a further look into this. But here comes my code:
public HttpRequestor getProxy(){
if("true".equals(config.getProperty("proxy","false"))){
String ip = "proxy.myproxy.com";
int port = 80;
final String authUser = "username";
final String authPassword = "password";
Authenticator.setDefault(new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(authUser, authPassword.toCharArray());
}
});
Proxy proxy = new Proxy(Proxy.Type.HTTP,new InetSocketAddress(ip,port));
HttpRequestor req = new StandardHttpRequestor(proxy);
return req;
}
return null;
}
As you can see I don't use the StandardHttpRequestor anymore. For the Dropbox code it is the following:
HttpRequestor requ = con.getProxy();
if(requ!=null)
config = new DbxRequestConfig(APP_NAME, Locale.getDefault().toString(),requ);
else
config = new DbxRequestConfig(APP_NAME, Locale.getDefault().toString());
As I already said, sometimes it works. Sometimes not. I'm going to write more info about that as soon as I know if it's because of the code or because of the proxy itself.
I'm a long time reader and first time user so please go easy on me.
I'm attempting to use preemptive auth with javax.ws.rs.client.Client. I've got this working with HTTPClient, but I can't figure out how to accomplish the same with a JAX authenticator.
HttpClient client = new HttpClient();
client.getParams().setAuthenticationPreemptive(true);
Credentials creds = new UsernamePasswordCredentials("user", "pass");
client.getState().setCredentials(AuthScope.ANY, creds);
I do have basic auth working with JAX. Here's my client:
public HttpsConnection() {
// configure ssl
final SslConfigurator sslConfig = SslConfigurator.newInstance().keyStoreFile(keyStore).keyPassword("pass");
final HostnameVerifier hostnameVerifier = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
final SSLContext sslContext = sslConfig.createSSLContext();
// configure client
final Client client = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(hostnameVerifier)
.register(new Authenticator(username, password)).register(JacksonFeature.class)
.register(new JsonObjectMapper()).build();
WebTarget target = client.target(base_url);
}
And here's my auth filter:
public class Authenticator implements ClientRequestFilter {
private final String user;
private final String password;
public Authenticator(String user, String password) {
this.user = user;
this.password = password;
}
public void filter(ClientRequestContext requestContext) throws IOException {
MultivaluedMap<String, Object> headers = requestContext.getHeaders();
final String basicAuthentication = getBasicAuthentication();
headers.add("Authorization", basicAuthentication);
}
private String getBasicAuthentication() {
String token = this.user + ":" + this.password;
try {
return "Basic " + DatatypeConverter.printBase64Binary(token.getBytes("UTF-8"));
} catch (UnsupportedEncodingException ex) {
throw new IllegalStateException("Cannot encode with UTF-8", ex);
}
}
}
Can anyone give me an example using UsernamePasswordCredentials with preemptive auth like I'm doing with HTTPClient above? I must be Googling for all of the wrong things because I just can't find an example.
And if my post totally sucks then please let me know before it gets closed by an OP =)