Problem
I am working on a Java based project at work(lets call it Project X) for which my latest task was to change the way it handles login. I think it’s best I provide some context before I describe my problem, so here we go,
Problem details
You see when you try to access a certain restricted area of a web-app when not logged-in the browser will show you a login prompt, and only when you enter the right credentials, will you be able to access that area of a web-app. That entire process of seeing the login prompt, entering the credentials etc requires human intervention and my task was to achieve all that programmatically i.e. without any human intervention for Project X.
Great!! the problem is now clear, so let’s look at the problem in the context of Project X in a bit more detail. In Project X, we have a login-page that calls a certain Servlet and passes the username and password, now my task was to invoke that RESTful endpoint while passing the username and password and the RESTful endpoint will respond with a cookie (assuming the credentials are correct) that has a session token that can be stored and used for subsequent requests.
How does the browser’s native login prompt work?
- When you try to access a certain restricted resource by typing the url in the browser
- The browser gets a HTTP 401 unauthorized response
- After which the browser shows you a login prompt
- Then you enter the username and password and click log-in
- The browser re-submits the request but this time with an extra header i.e. Authorization: Basic username password
- The username and password are base64 encoded so the header would actually look something like this Authorization:Basic ILQtaW46YWRtaW4=
- If you were successfully authenticated, you will access the resource you were trying to access
So what was my goal?
Solution
public class ClientAuthentication {
public static void main(String[] args) throws Exception {
String host = "";
int port = 0000;
String username = "username";
String password = "password";
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(host, port),
new UsernamePasswordCredentials(username, password));
final BasicCookieStore cookieStore = new BasicCookieStore();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultCookieStore(cookieStore)
.build();
try {
String urlToQuery ="";
HttpGet httpget = new HttpGet(urlToQuery);
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
@Override
public String handleResponse(
final HttpResponse response) throws ClientProtocolException, IOException {
List<Cookie> cookies = cookieStore.getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
return "";
}
};
httpclient.execute(httpget, responseHandler);
} finally {
httpclient.close();
}
}
}
Now the above example works great with the 4.4.1 version of the libs, but you see Project X uses 4.1.2 version of the libs and since this was something very basic, I had to figure out how to make it work with the older libs. What you see below is code that does something similar but with the older version of the libs.
public class AuthWithFourPointOne {
public static void main(String[] args) throws Exception {
String host = "";
int port = 0000;
String username = "username";
String password = "password";
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(new AuthScope(host, port), new UsernamePasswordCredentials(username, password));
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setCredentialsProvider(credsProvider);
try {
String url = "";
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpclient.execute(httpGet);
String cookie = "";
//in my case the cookie in the header was called Set-Cookie
for(Header header:response.getAllHeaders()){
if(header.getName().contains("Set-Cookie")) {
cookie = header.getValue();
}
}
} finally {
httpclient.getConnectionManager().shutdown();
}
}
}
As usual, if you find any of my posts useful support me by buying or even trying one of my apps on the App Store.
Also, if you can leave a review on the App Store or Google Play Store, that would help too.
0 Comments