Isn't username and password send to server?
When username and password is entered into the pop-up in Web browser (or by similar manner in other web clients) those are not send to server as they are, but send after encoding in a way that the receiving server side can decode and extract the username and password to check the validity. This encoding approach is not secure as the encryption approaches like AES.Sample request with basic authentication header for username="Aladdin" and password="open sesame" looks as below.
GET /myweb/index.html HTTP/1.1
Host: localhost
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Web clients create a string by concatenating the username and password with a colon (":") as username:password. Then it is encoded in base 64 and is sent to the server, so that the server can do the reverse to extract username and password.
Example Program
Code example imports a class named Imported class named org.apache.commons.codec.binary.Base64 from commons-codec-1.6 available at http://commons.apache.org/codec/download_codec.cgi. Please download it yourself and add the commons-codec-1.6.jar file to the CLASSPATH.package org.kamal.http.basicauth;
import org.apache.commons.codec.binary.Base64;
public class HttpBasicAuthenticationHeader {
public static void main(String[] args) {
final String username = "Aladdin";
final String password = "open sesame";
System.out.println("Input\t: username [" + username + "], password [" + password + "]");
final String encodedText = createEncodedText(username, password);
System.out.println("Encoded Text : " + encodedText);
final String[] userDetails = decode(encodedText);
System.out.println("Decoded\t: username [" + userDetails[0] + "], password [" + userDetails[1] + "]");
}
private static String[] decode(final String encodedString) {
final byte[] decodedBytes = Base64.decodeBase64(encodedString.getBytes());
final String pair = new String(decodedBytes);
final String[] userDetails = pair.split(":", 2);
return userDetails;
}
private static String createEncodedText(final String username, final String password) {
final String pair = username + ":" + password;
final byte[] encodedBytes = Base64.encodeBase64(pair.getBytes());
return new String(encodedBytes);
}
Output of the program:
Input : username [Aladdin], password [open sesame]
Encoded Text : QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Decoded : username [Aladdin], password [open sesame]
As you can see the above program can encode and decode as expected.
I used sun.* library earlier, but apache one useful. thanks.
ReplyDeleteGood write-up. Personally, I've actually ended up using javax.xml.bind.DatatypeConverter to do the base64 encoding, since it's included in Java SE since 6.0. (And I don't even like JAXB)
ReplyDeleteHi Johannes,
ReplyDeleteGlad to hear this helped you, and thanks for the encouragement.
KIT.
good stuff kamal
ReplyDeleteThanks Ruka.
ReplyDeleteHI Kamal,
ReplyDeleteCan you provide complete java sample code for setting up HTTPS Basic authentication header and invoking a POST interface?
Regards,
Nasir
Hi can you please provide java spring integration example to set basic authentication using header enricher
ReplyDeleteGreat post, what you said is really helpful to me. I can’t agree with you anymore. I have been talking with my friend about, he though it is really interesting as well
ReplyDelete