http 407 proxy authentication required : how to handle in java code - java

System.setProperty("http.proxySet", "true");
System.setProperty("java.net.useSystemProxies", "true");
System.setProperty("http.proxyHost", "192.168.1.103");
System.setProperty("http.proxyPort", "3128");
System.setProperty("http.proxyUser", "user123");
System.setProperty("http.proxyPassword", "passwD123");
url = new URL("http://www.google.co.in");
every time when I am using this code IOException throws which say HTTP response code 407.
HTTP 407 means proxy authentication required. why this problem is coming while I set proxyUser and proxyPassword.
http 401 will occur if I put wrong password but it always give me 407, means my code does not take username and password. In above code user123 is username and passwD123 is password for proxy authentication.

http://blog.vinodsingh.com/2008/05/proxy-authentication-in-java.html
I found the solution thanks Mr. Vinod Singh.
Proxy authentication in Java
The usual corporate networks provide internet access via proxy servers and at times they require authentication as well. May applications do open the connections to servers which are external to the corporate intranet. So one has to do proxy authentication programmatically. Fortunately Java provides a transparent mechanism to do proxy authentications.
Create a simple class like below-
import java.net.Authenticator;
class ProxyAuthenticator extends Authenticator {
private String user, password;
public ProxyAuthenticator(String user, String password) {
this.user = user;
this.password = password;
}
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user, password.toCharArray());
}
}
and put these lines of code before your code opens an URLConnection-
Authenticator.setDefault(new ProxyAuthenticator("user", "password"));
System.setProperty("http.proxyHost", "proxy host");
System.setProperty("http.proxyPort", "port");
Now all calls will successfully pass through the proxy authentication.

The answer to use an Authenticator is correct for the general case. However, another cause of HTTP 407 in Java 8u111 and later is if you are using BASIC authentication against the proxy.
In this case, add this system property:
-Djdk.http.auth.tunneling.disabledSchemes=
I found this out from: https://confluence.atlassian.com/kb/basic-authentication-fails-for-outgoing-proxy-in-java-8u111-909643110.html

#GauravDS
You mentioned:
http://blog.vinodsingh.com/2008/05/proxy-authentication-in-java.html
I found the solution thanks Mr. Vinod Singh.
Proxy authentication in Java
The usual corporate networks provide internet access via proxy servers and at times they require authentication as well. May applications do open the connections to servers which are external to the corporate intranet. So one has to do proxy authentication programmatically. Fortunately Java provides a transparent mechanism to do proxy authentications.
Create a simple class like below-
.
.
.
and put these lines of code before your code opens an URLConnection-
Authenticator.setDefault(new ProxyAuthenticator("user", "password"));
System.setProperty("http.proxyHost", "proxy host");
System.setProperty("http.proxyPort", "port");
Now all calls will successfully pass through the proxy authentication.
What if the site you are connecting to also requires a username/password to allow you.
Setting a Default Authenticator(Authenticator.setDefault) will fail I guess when the external site will look for authenticated user.
Any views?....Someone ?
Edit:1
Used this code earlier and was getting the error (407) Proxy Authentication Required.
I believe that was because the authentication was requested by different hosts. and when you set a default authenticator with one user/pass for one host, then the authentication will fail for other requesting host. I made the following change yesterday to SimpleAuthenticator class and now it works like a charm.
protected PasswordAuthentication getPasswordAuthentication()
{
String requestingHost = getRequestingHost();
if (requestingHost == proxyHost){
System.out.println("getPasswordAuthentication() request recieved from->" + requestingHost );
return new PasswordAuthentication(proxyuser,proxypass.toCharArray());
}
else{
System.out.println("getPasswordAuthentication() request recieved from->" + requestingHost );
return new PasswordAuthentication(sharepointusername,sharepointpassword.toCharArray());
}
}
More info here: http://blog.ashwani.co.in/blog/2013-07-29/access-sharepoint-webservices-from-java-behind-proxy/

Related

Restlet Request object doesn't contain authentication information

The codebase I'm working with has two versions: the first (older) version uses v1.0.0 of the Restlet framework, and the latter (newer) version uses v2.2.2.
When a user queries both versions of my service with cURL and provides their username and password as a base64 encoded String, it works. Similarly, both versions accept the encoded String in the Authorization: Basic ... header.
Where they differ is when I attempt to call the service using HttpURLConnection. The former works, the latter doesn't.
This is the general idea of how the tool that calls my service works:
final String xx_userid = userid; // userid set above
final String xx_pwd = pwd; // pwd set above
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
xx_userid, xx_pwd.toCharArray());
}
});
// ... some more code ...
URL url = new URL(url_string); // url_string is the endpoint of my service
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("Accept", "text/xml");
The above code works for the older codebase (that is, I get a 200 OK back as well as the expected XML response). However, for the new codebase, I get a 403 Unauthorized back.
Here's the snippet in my new codebase that's supposed to get the username and password from the request:
#Override
protected boolean authenticate (Request request, Response response) {
String user = null;
String pass = null;
user = request.getChallengeResponse().getIdentifier();
pass = new String(request.getChallengeResponse().getSecret());
// ... some more code ...
}
Both user and pass end up staying null, because the getChallengeResponse() method returns null.
Does anyone know why this code works for v1.0.0 of the Restlet framework, but not for v2.2.2? Or is there something else I'm missing?
Some other (probably irrelevant) information:
The old codebase:
Is running in Tomcat v7.0.55
Is hosted on a RHEL7 machine
Doesn't have a load balancer
The new codebase:
Is running in Tomcat v7.0.55
Is hosted on an EC2 instance (Amazon Linux AMI)
Uses Amazon's application load balancer (ALB) to point to the different EC2 instances
The load balancer has a different domain name than the service instances
Thanks in advance. Please let me know if there's any more information that I could provide to make this easier to debug.

set ProxyAuthorizationPolicy for CXF httpConduit doesn't work

I'm Using CXF 3.1.5, I'm trying to make it work with proxy. if there is no username and password for the proxy, then it works; if there is an username and password for the proxy, then it doesn't work. here is my code:
//to create my own http conduit
bus.setExtension(new TLSAndProxySupportedHTTPConduitFactory(settings, HTTPConduitFactory.class);
//to get wsdl definition
Definition definition = bus.getExtension(WSDLManager.class).getDefinition(uri);
TLSAndProxySupportedHTTPConduitFactory implements HTTPConduitFactory, and will create a TLSAndProxySupportedHTTPConduit which extends URLConnectionHTTPConduit, in TLSAndProxySupportedHTTPConduit, here is the related code for proxy settings:
//HTTPClientPolicy settings works
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setProxyServer(proxy.getHostName());
httpClientPolicy.setProxyServerPort(proxy.getPort());
this.setClient(httpClientPolicy);
if (proxy.getUserName() != null) {
//ProxyAuthorizationPolicy settings doesn't work
this.getProxyAuthorization().setUserName(proxy.getUserName());
this.getProxyAuthorization().setPassword(proxy.getPassword());
}
Please do remember if the proxy has no username and password, everything works just fine.and if the target URL for loading WSDL definition is started with https(https is required for me), the proxy doesn't work. if it's started with http, then the proxy with username and password works well.
Find a solution:
The Reason is
The Java Secure Socket Extension (JSSE) library from Sun Microsystems lets you access a secure Web server from behind a firewall via proxy tunneling. To do this, the JSSE application needs to set the https.ProxyHost and https.ProxyPort system properties. The tunneling code in JSSE checks for "HTTP 1.0" in the proxy's response. If your proxy, like many, returns "HTTP 1.1", you will get an IOException. In this case, you need to implement your own HTTPS tunneling protocol.
Referance:http://www.javaworld.com/article/2077475/core-java/java-tip-111--implement-https-tunneling-with-jsse.html
and https://community.oracle.com/thread/1534538
Then you could overwrite method setupConnection of URLConnectionHTTPConduit.
#Override
protected void setupConnection(Message message, Address address, HTTPClientPolicy csPolicy) throws IOException {
super.setupConnection(message, address, csPolicy);
HttpURLConnection connection = (HttpURLConnection) message.get(KEY_HTTP_CONNECTION);
decorateHttpsURLConnection((HttpsURLConnection) connection);\
message.put(KEY_HTTP_CONNECTION, connection);
}
in the method decorateHttpsURLConnection:
httpsConnection.setSSLSocketFactory(new SSLTunnelSocketFactory(getProxy(), sslContext.getSocketFactory()));

Send email OAUTH2 SMTP Outlook Java

I am using the scopes: mail.send, mail.readwrite, mail.read, offline_access, openid, email, and profile (although I am fairly confident I do not need all of these -> goal is to read inbox and send emails, while also getting email and name if they exist).
I am then connecting to SMTP server with the following code:
OAuth2Authenticator.connectToSmtp("smtp-mail.outlook.com",
587,
user.getOutlookUid(),
accessToken,
true);
The code that actually connects to the server is here:
public static SMTPTransport connectToSmtp(String host, int port, String userEmail, String oauthToken, boolean debug)
throws Exception {
Properties props = new Properties();
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");
props.put("mail.smtp.sasl.enable", "true");
props.put("mail.smtp.sasl.mechanisms", "XOAUTH2");
props.put("mail.smtp.sasl.mechanisms.oauth2.oauthToken", oauthToken);
Session session = Session.getInstance(props);
session.setDebug(debug);
URLName unusedUrlName = null;
SMTPTransport transport = new SMTPTransport(session, unusedUrlName);
// If the password is non-null, SMTP tries to do AUTH LOGIN.
String password = "";
transport.connect(host, port, userEmail, password);
return transport;
}
Okay, now I can get to the most frustrating part... I have used the "connectToSMTP" method to connect to Gmail and it worked perfectly.
OAuth2Authenticator.connectToSmtp("smtp.gmail.com",
587,
user.getGoogleUid(),
accessToken,
true);
So ultimately my question is "what am I doing wrong?" or "what can I update to be able to send emails through Outlook"? I have seen that Outlook has a REST API, but that is plan B. Is there something different about Outlook vs Gmail?
Some things I have considered:
Scope did not request enough access (so I probably am asking for too much now)
access_token was stored incorrectly or encoded in some way (tried decoding it from base_64 which provided nothing). I am able to use my refresh_token to update the access_token so that tells me I am probably storing them correctly.
I tried passing null for the password. Also passed in the actual password and that WORKED, but I have the access_token and refresh_token so I shouldn't need to ask for their explicit password. Also this would be dangerous and sketchy to ask of users.
I tried manually connecting to the smtp server using "openssl s_client -crlf -starttls smtp -connect smtp-mail.outlook.com:587", but it seemed to think my access_token was wrong "535 5.0.0 OAuth failed: OAuth authentication failed due to Invalid token. Code -2147184118" That number when taken two's complement and converted to hex is 0x8004920a. Helped in searches but was to no avail.
I have done a lot of searching for this and will continue now to post this everywhere. A lot of resources for it working with Gmail, but as previously stated I already have it working for Gmail. Something seems different for Outlook. Also I have encountered lots of posts regarding email forwarding on an email client... I am semi-creating an email client so going through outlook.com settings doesn't help me.
Another concern that a buddy of mine had was that my access token was really long, contributing to what the manual smtp server claimed. It is 1188 characters long. It's something like 'EwB4Aul3BAAUo4xeBIbHjhBxWOFekj4Xy2...x9stHxi2K/VFggE=' (obviously I hid most of the characters).
Preemptive THANK YOU for anyone who offers advice or finds my issue. Especially why I can pass in the email password and that fails, but using the oauth access_token fails.
Try using "pop3://user:password#host:port/INBOX". to retrieve email from the inbox ,
more information can be found out https://javamail.java.net/docs/api/com/sun/mail/pop3/package-summary.html
hope this helps : https://technet.microsoft.com/en-ca/dn44016. Properties props = new Properties();
props.put("mail.imap.ssl.enable", "true"); // required for Gmail
props.put("mail.imap.auth.mechanisms", "XOAUTH2");
Session session = Session.getInstance(props);
Store store = session.getStore("imap");
store.connect("imap.gmail.com", username, oauth2_access_token);

How authenticate a rest call from behind a corporate proxy using Rest-Assured?

I'm trying to call a rest service via our corporate proxy but keep getting the response:
407 Proxy Authentication Required. Forefront TMG requires authorization to fulfill the request. Access to the Web Proxy filter is denied.
Can anyone suggest anything else I can try, or an alternative to RestAssured that supports NTLM?
This is my current code:
PreemptiveBasicAuthScheme auth = new PreemptiveBasicAuthScheme();
auth.setUserName("my username");
auth.setPassword("my password");
// was getting desperate so tried adding this
System.setProperty("http.proxyHost", "XXXX");
System.setProperty("http.proxyPort", "8080");
System.setProperty("http.proxyUser", "my username");
System.setProperty("http.proxyPassword", "my password");
System.setProperty("https.proxyHost", "XXXX");
System.setProperty("https.proxyPort", "8080");
System.setProperty("https.proxyUser", "my username");
System.setProperty("https.proxyPassword", "my password");
Response r = RestAssured
.given()
// tried with and without this
.header("Proxy-Authorization", auth.generateAuthToken())
.proxy("XXXX", 8080)
.get(fullPath, key, key);
There were a couple of issues here - the first I've sorted, the second I'm still blocked on.
Setting the proxy authentication was a simple matter of setting the correct header (as has been noted in many other posts):
.header("Proxy-Authorization", auth.generateAuthToken())
What was blocking me was that I'm calling a service running on https rather than http and the proxy does not appear to be used... so back to the drawing board.

Proxy Authentication Failed error

I'm trying to access an FTP server through an FTP SITE Proxy to bypass a firewall using it.sauronsoftware.ftp4j.FTPClient I know my username/password is correct because I can connect using FileZilla. I tried using Authenticator, but it has no use. Code:
import java.net.Authenticator;
import it.sauronsoftware.ftp4j.FTPClient;
import it.sauronsoftware.ftp4j.connectors.FTPProxyConnector;
...
FTPClient client = new FTPClient();
FTPProxyConnector connector = new FTPProxyConnector(String "proxyHost", int proxyPort);
client.setConnector(connector);
Authenticator.setDefault(new Authenticator() {
#Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("proxyUser", "proxyPass".toCharArray());
}});
System.setProperty("ftp.proxyHost", "proxyHost");
System.setProperty("ftp.proxyPort", "proxyPort");
System.setProperty("ftp.proxyUser", "proxyUser");
System.setProperty("ftp.proxyPass", "proxyPass");
System.out.println("Proxy Accessed");
client.connect("ftpHost");
client.login("ftpUser", "ftpPass");
Gives me this error: java.io.IOException: Proxy authentication failed
Things I have tried:
Using the alternate constructor (String, int, String, String).
Removing Authenticator
Using just Authenticator, without the FTPProxyConnector
Authenticating before setting the connector, and vice versa.
However, when I am JUST using the Authenticator, I get a different error saying Connection timed out.
Both errors occur on line client.connect("ftpHost");
ANY help would be appreciated.
Note: The FTP Proxy Connector
EDIT: I found out that the proxy is used to bypass a Firewall-1 Checkpoint -- if this helps.
Check password property name. It's name is ftp.proxyPassword, and not ftp.proxyPass.
System.setProperty("ftp.proxyUser", "proxyUser");
System.setProperty("ftp.proxyPassword", "proxyPass");
Try it and let us know your results!
Check password property name. It's name is ftp.proxyPassword, and not ftp.proxyPass.
System.setProperty("ftp.proxyUser", "proxyUser");
System.setProperty("ftp.proxyPassword", "proxyPass");
Try it and let us know your results!
I found the solution...
I discovered that the FTP client was responding with a different response code:
200-User <username> authenticated by FireWall-1 authentication
In the source code of FTPProxyConnector, a response code of anything other than the regular
230-Connected to server. Logging in...
will throw an error.
I had to decompile the class file for FTPProxyConnector and then modify the source code, then recompile and save it back to the jar. Worked like a charm.

Categories

Resources