Connecting to Remote Url Which Requires Authentication Using Java

Connecting to remote URL which requires authentication using Java

You can set the default authenticator for http requests like this:

Authenticator.setDefault (new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication ("username", "password".toCharArray());
}
});

Also, if you require more flexibility, you can check out the Apache HttpClient, which will give you more authentication options (as well as session support, etc.)

Connecting to remote Site require Authentication

just visited https://www.quora.com/ and it dosen't look like a basic authentication. You will need to submit a form with the HTTP type as POST with the variable names as 'email' and 'password' (You can view the source of the site and find out the expected parameters).

Looks like an AJAX mechanism is used to perform the authentication with the site. You will need to find out the page to which this request is submitted (asynchronous or otherwise).

After all this, there is a possibility that the secured connection of the site (https) may not allow you to perform the desired action (depends on SSL configuration of the server)

connect to a URL using Basic authentication in Java - java.net.ConnectException: Connection refused: connect

Be carefull to difference ProxyAuthentication from URI authentication.

Here you have an example for uri authentication [if u need to authenticate on the URI ] :

        BASE64Encoder encoder = new BASE64Encoder();//import sun.misc.BASE64Encoder;
String authString = name + ":" + password;
String authStringEncoded = encoder.encode(authString.getBytes());
setHeader("Authorization", "Basic " + authStringEncoded);

This for proxy authentication [ if u need to go out internet though a proxy ]:

            BASE64Encoder encoder = new BASE64Encoder();
String authString = name + ":" + password;
String authStringEncoded = encoder.encode(authString.getBytes());
setHeader("Proxy-Authorization", "Basic " + authStringEncoded);

Maybe, aslo, you can probe Apache utilities to get a correct encoded UserName / password

Something like this pseudo code:

Header  auth_header=
new DigestScheme().authenticate(new UsernamePasswordCredentials(authUser.asString(),
authPwd.asString()),
commonsHttpRequest,
new BasicHttpContext());

After, just:

urlConnection.setRequestProperty("Authorization", auth_header.getValue());

How do I connect to a remote URL which requires Spring Security forms authentication (Java)?

It is a bit hard to understand what your application is trying to do, but my best guess is that your 'portal' sits between the user's browser and the application, and you are trying to use the some stored credentials for the application to authenticate on behalf of the users.

There are two things you need to watch for / deal with.

The responses from the application will contain SetCookie headers of some sort. The cookies need to be handled carefully. Depending on the security model you are using:

  • They could be saved in the portal and used for future requests to the application.
  • They could be relayed to the user's browser. The portal would also need to pass the cookies through in future requests to the application. (This approach needs to be handled carefully to deal with possible issues with session token leakage.)

Also, be aware that SpringSecurity changes the session cookie when login succeeds. If you don't capture the new session cookie and use them in follow on requests to the application, those requests won't be authenticated.

The application's login mechanism is clearly trying to redirect you (the portal) to the "default" place after logging in, and this is inappropriate. There are two simple fixes for this:

  • Have the portal detect the final redirect and treat it as an indication that you've successfully logged in. Then have the portal repeat the request for the page you were originally requesting from the application using the new cookie (see above).

  • IIRC, there's an extra parameter you can add to a j_spring_security_check request that tells the application where to return on successful login. I can't recall the details ...


I thought that forwarding the setCookie response header from the RA into the portal's response to the browser would be all that is needed to transfer the cookie/session id to the user's new browser window. Is that not correct?

That will cause the browser to set the RA's cookie for the portal context. That won't work unless the RA and portal are in the cookie's "scope" (for the want of a better word).

Question is, how do I display this on/through the portal? Do I just have to copy all the content over and map all the relative links accordingly? And, as you state, continue to proxy all requests to the app through the portal, passing the cookie each time? Is there any way to avoid copying/modifying the markup?

You do need to massage the markup. But exactly what massaging is required is not entirely clear. I think you'll need to map the relative links so that when the user's browser sees them they point to the portal. Then, arrange that the portal relays requests to the RA with the appropriate cookies.

One tool that you can use to deal with relative links is the HTML <base> element. In fact, this potentially easier to deal with than absolute links ... if you map everything via the portal.

But beware that there are all sorts of things that can cause grief in this process. For example, you've got to beware of the "same source" restriction, and with javascript with embedded URLs for the RA.

Android 401 Error connecting to REST service using HttpURLConnection

If the resource is protected by "Digest" then sending a "Basic" authorization scheme in your code will not work because the server would not recognize it.

Secondly, by using a "preemptive" authentication, setting the Authorization header w/o it being requested is kind of a security hole. You will be sending information to the server that it has not requested.

Thirdly, the "Authenticator.setDefault" most likely will not be requested as there was some significant back-and-forth caused by MicroSoft's implementation of HTTP digest authentication (YMMV may vary on my recollection of this). As such, Sun/Oracle decided to leave this behavior disabled by default as per this document.

That said, you may be better off looking into utilizing the Apache HTTP client bundled with Android to do this. There is a bundled implementation Digest Authentication included. There is an example of "preemptive" digest authentication located here.

Couple of caveats to be aware of:

  • Pay CLOSE attention to the "HttpHost" stored in "target" - this MUST MATCH EXACTLY the host name, protocol port, and protocol scheme used in the URL being retrieved.
  • The example provided is for HTTP Client 4.2.x. I am not 100% sure of the version included in Android but you should be able to locate working examples.

Update Submitter has provided additional comments with regard to the statement that it is recommended by Google to use the HttpURLConnection with articles here and here.

While I trust the statements made by Tim Bray with regard to the reasoning as to why you should be using the provided HttpURLConnection object for performing these calls, I do not agree that they should be immediately accepted on face value.

There is no indication as to the level of support of digest authentication provided by the implementation in Android. As I mentioned earlier, the HttpURLConnection does not support immediately as it has been known to be buggy.

If you are decided that you are going to use HTTP Digest Authentication, regardless of the fact that it has been deemed unstable by the majority of the community, I would attempt to set the following system properties in your application as EARLY as possible during the Android lifecycle:

  • http.auth.digest.validateServer="true"
  • http.auth.digest.validateProxy="true"

By doing so, this should enable the digest authentication scheme.

I am, again, going to re-iterate that the Apache HTTP Client bundled with Android was developed and designed specifically to address short-comings of the basic Java HttpURLConnection, providing much a much broader and robust client for dealing with HTTP(s) based data streams.

I would recommend trying a couple of things as well, see if you can configure your container to provide "Basic" authentication protection. The other, more complex option, would be to possibly provide X.509 Certificate Based authentication.

I hope that this clarification helps you get to your goal.

Java: fetch URL with HTTPBasic Authentication

That seems to be a bug in Java.

Have you tried using alternative HTTP clients, such as the library from Apache?

Or instead of using the Authenticator, manually setting the header?

URL url = new URL("http://www.example.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Authorization", "Basic OGU0ZTc5ODBkABcde....");

The token value is encodeBase64("username:password").



Related Topics



Leave a reply



Submit