Java\Groovy - java.io.IOException: Authentication failure in simple authenticated HTTP request - java

I'm using Groovy\Java. I'm trying to download a file from a server with a simple HTTP GET. This code works on every computer we tried, except for my coworker's computer.
new File(fullFilePath).withOutputStream { out ->
url = new URL(COMPLETE_URL).openConnection()
Authenticator.setDefault (new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication (USER, PASSWORD);
}
});
out << url.inputStream
}
The strange thing is that this code works perfectly on my computer and on an AWS instance, on Windows 10 and Windows Server 2012, and it DOES NOT work on my coworker's computer, on Windows 10. All 64bit.
We all have the same Java version. Antivirus and Firewall are disabled. I tried with his credentials and he tried with mine, it still doesn't work only from his computer.
Error:
java.io.IOException: Authentication failure
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1695)
  at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439)
...
What else could we try and check?

Using Authenticator.setDefault() is a bad approach for this. It will cause Java to send your username and password on ANY request the JVM makes which requests credentials.
Why this is failing only on one machine is hard to tell, but likely the Java configuration must be different.
In any case, try changing your code to just set the authentication header on each request. That will make your code less reliant on Java's internals and will not just send your credentials on each request the JVM might make in the future:
def authHeaderValue = 'Basic ' + Base64.encoder.encodeToString("$USER:$PASSWORD".bytes)
new File(fullFilePath).withOutputStream { out ->
connection = new URL(COMPLETE_URL).openConnection()
connection.setRequestProperty('Authorization', authHeaderValue)
out << connection.inputStream
}
I wrote a blog post about making HTTP requests in Groovy without libraries, you may want to check it out.

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.

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.

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

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/

How to log into Business Objects using Active Directory or LDAP

Edit: Appended "or LDAP" to question title to indicate that I would be fine to have a solution which made it possible for me to authenticate with LDAP credentials.
My Question: How do I authenticate a BusinessObjects session using credentials with Active Directory?
Example: I have (I think) an example from SAP on how to do this in .NET but I can't seem to find a similar solution for Java. (See this pdf and search for "Modify the .NET Web Application to enable Kerberos").
Currently: I have a solution to authenticate using an Enterprise Account:
/**
* Logs into BusinessObjects. Sets the reportEngine and biPlatform
*/
public void loginToBusinessObjects() throws AxisFault, MalformedURLException, Exception {
LogHelper.println("Server connection: " + boServer);
URL boConURL = new URL(boServer);//set connection URL
connection = new com.businessobjects.dsws.Connection(boConURL);
boSession = new Session(connection); //setup new session
EnterpriseCredential credential = EnterpriseCredential.Factory.newInstance();
credential.setLogin(boUsername);
credential.setPassword(boPassword);
LogHelper.println(boUsername + ": ##password##");
boSession.login(credential); //login to server
...
}
The code above works great.
Now: I want to be able allow users to give their Active Directory credentials and authenticate using those. I can't seem to find a way to do this however. Documentation on the code above can be found in that same pdf searching for "Logging in to a server."
Note: I could be going about this all wrong. My organization uses the same credentials for Active Directory and LDAP Authentication. If there's a way to do this using LDAP that may be sufficient. Thanks.
The answer assumes you have set up the Active Directory and/or LDAP authentication for users and the user(s) have an alias to that authentication method. This should be verifiable by logins into InfoView.
You should be able to do it by using credential.setAuthType(authType).
Where authType is
"secEnterprise" default value
"secLDAP"
"secWinAD"
Seems and makes sense that by default the AuthType is set to secEnterprise.
Note: I'm still on R3 which has a slightly different authentication mechanism and I have not specifically tried this solution.
Important Edit: The documentation (which is awful for BusinessObjects and anyone reading this probably already knows that) says that for active directory you use "secAD". However, in my testing I was able to successfully authenticate using "secWinAD" which does not appear anywhere in their documentation at all :-/ (that I could find).

Authenticating with Active Directory via Kerberos

I'm working on building an android application which requires different levels of authentication, and I would like to do so using Active Directory.
From what I've read, using Kerberos is the way Microsoft suggests. How do I do this for Android? I see the javax.security.auth doc, but it doesn't tell me too much.
I also saw a note somewhere that Kerberos does not contain user groups - is this true? In that case, would I have to somehow combine LDAP as well?
EDIT
The main goal here is achieving an LDAP connection to the active directory in order to authenticate and give the user correct permissions for the enterprise Android application. The real barrier here is the fact that Google left out many of the Java Web Services API from it's port to android. (i.e. javax.naming) Also, many of the connection mechanisms in the Android jar seem to be only included as legacy code, and they in fact actually do nothing.
For that you might be better off just staying completely within LDAP and don't venture into the kerberos. Kerberos gives you advantage of Single Sign On, but since your android app doesn't have any credentials already in place it doesn't really help you. I guess google had their own reasons not to include the javax.naming into the distro. It is pretty heavy stuff.
You might be able to either port the stuff yourself from java runtime library sources, or might be better off using native LDAP library. For example this one.
Just remember to use secure LDAP connection or at least secure authentication method. More info about this is here.
I found the documentation here to be really useful when I was writing my code to authenticate with my Kerberos server. Here's how I authenticate with my kerberos server, but you might need to tweak it for yours (hence me including the link):
public static final int REGISTRATION_TIMEOUT = 30 * 1000; // ms
private static DefaultHttpClient httpClient;
private static final AuthScope SERVER_AUTH_SCOPE =
new AuthScope("urls to kerberos server", AuthScope.ANY_PORT);
public static DefaultHttpClient getHttpClient(){
if(httpClient == null){
httpClient = new DefaultHttpClient();
final HttpParams params = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, REGISTRATION_TIMEOUT);
ConnManagerParams.setTimeout(params, REGISTRATION_TIMEOUT);
}
return httpClient;
}
public static boolean authenticate(String username, String password)
{
UsernamePasswordCredentials creds =
new UsernamePasswordCredentials(username, password);
DefaultHttpClient client = getHttpClient();
client.getCredentialsProvider().setCredentials(SERVER_AUTH_SCOPE, creds);
boolean authWorked = false;
try{
HttpGet get = new HttpGet(AUTH_URI);
HttpResponse resp = client.execute(get);
authWorked = resp.getStatusLine().getStatusCode() != 403
}
catch(IOException e){
Log.e("TAG", "IOException exceptions");
//TODO maybe do something?
}
return authWorked;
}
Have you looked at using JCIFS? Based on these questions [1] [2] and this site, JCIFS works under Android. The JCIFS site has a simple NTLM Authenticator example that could help get you started. However, based on this Samba list message, you will need to use LDAP and custom code to get the user's groups.
Try this tutorial from Oracle. My code likes a charm. Hopefully everything is included in Android's VM distro.

Categories

Resources