Engineering Full Stack Apps with Java and JavaScript
Authentication is the process of verifying if the user, usually with a username and password. Once authenticated, we may call a user as an authenticated user or a logged in user.
Java EE provides four different ways to authenticate a user:
Basic Authentication
Digest Authentication
Form Authentication
SSL Certificates
Data used to authenticate a user are called credentials; while the first three rely on username and password provided by user, the fourth one relies on encryption techniques and certificates.
In basic authentication, client (e.g. browser) should ask the user for a username and a password. A client browser usually does this using a pop up window.
Basic authentication uses HTTP headers to request authentication data from the client and to transmit the input data back to the server.
HTTP Authentication asks for credentials three times before returning an error.
Advantage of basic authentication
Simple to implement
Disadvantage of basic authentication
Platform and browser dependent dialog window is shown
Transmits data in plain, unencrypted, base64 format. A third party may eavesdrop on the http packets and read the username and password.
DIGEST authentication is similar to BASIC authentication, but with an additional precaution to prevent a third party from doing eavesdrop on the http packets and easily read the username and password, which was one of the disadvantages of BASIC authentication.
In DIGEST authentication, a message digest of the password is passed rather than original password. A message digest is a calculated value from the original content using a hashing algorithm. Original message cannot be recreated from a message digest. The server will also have to generate the digest for the stored password using the same hash algorithm and then compare the digest sent by client and the one generated by it, instead of comparing original passwords.
An unauthorized party could eavesdrop on the digest for the password and may use that to authenticate themselves. To Overcome this, the server passes some additional data called salt (e.g. current timestamp) to the client when it requests authentication. The client uses this timestamp also while hashing and hence the timestamp will be different for every request for authentication. Only someone who knows the original password and current salt can be authenticated
Java EE-compliant containers are not required to support this authentication method, but must support the BASIC, FORM and SSL authentication.
Advantage of digest authentication
Simple to implement
Difficult for third party to evesdrop and find password.
Disadvantage of digest authentication
Platform and browser dependent dialog window is shown
FORM Authentication
You may use Form Based Authentication to provide your own login form rather than relying on browser to provide one. This form can be created with the same looks of rest of your pages, thus integrating the authentication process with the rest of your website
You could program your own Form Based Authentication mechanism, but the container already provides a template for the layout of the form. Using this default layout allows to do declarative authentication. The container's template requires a username and the password; it obtains these using (X)HTML input fields:
<form method="POST" action="j_security_check">
<input type="text" name="j_username"/>
<input type="password" name="j_password"/>
</form>
Important things to consider while doing form based authentication are
The action destination must be j_security_check, which alerts the container that this is the default authentication form.
The names of the input fields should be j_username and j_password, as container will look for these when you submit a form to j_security_check.
We will also need to make necessary changes in the web.xml to specify the login form page.
Advantage of Form Authentication
Easily integrates with the rest of the website.
Disadvantage of Form Authentication
The data is still sent unencrypted, as with Basic authentication.
For true security, you would need to use Form Based Authentication over a Secure HTTP channel, so that all submitted data (the username , and the password in particular) are encrypted. This is declared as part of the confidentiality requirements of an application.
We can use SSL certificates to secure the communication channel. Both the client and server are required to identify themselves by providing appropriate credentials. This typically occurs by comparing the clients Public Key Certificate (PKC) with a copy stored on the server. This is the most secure form of authentication since it is difficult to fake a certificate.
JavaEE allows us to use SSL certificates for authentication simply by making the appropriate declarations in the deployment descriptor.
Advantage of SSL Authentication
This is the most secure form of authentication since it is difficult to fake a certificate.
Disadvantage of SSL Authentication
Each client authenticated using this method must have its own Public Key Certificate, which is not something most of the general public possess.
Moreover, the server must already own a copy of the certificate for comparison purposes, which implies that a server administrator has taken the time to establish a database of known certificates.
The use of SSL certificates for authentication is usually limited to internal networks and intranets where both the client and server machines are under the control of a single authoritive body.
We can specify the type of authentication we want using the <auth-method> element inside the <login-config> element, which is inside the <web-app> element. Possible values for the <auth-method> element are BASIC, DIGEST, CLIENT-CERT and FORM. While BASIC, DIGEST and CLIENT-CERT types are configured similarly, FORM type is configured a bit differently.
There may only be one <login-config> element per deployment descriptor and hence the authentication method will be same across the entire web application.
The <login-config> element also has a <realm-name> sub element which is mostly used with BASIC or DIGEST authentication, and is displayed on the popup dialog window for getting the password. Realm names may be considered as a human readable textual reminder about the facility tried to access.
BASIC and DIGEST are the easiest to configure.
<web-app>
…
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Authentication Required</ realm-name >
</login-config>
…
<web-app>
DIGEST can be substituted for BASIC without any other changes.
FORM authentication will also require you to specify the login form and an error form:
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/login-failed.html</form-error-page>
</form-login-config>
</login-config>
CLIENT-CERT is configured similar to BASIC/DIGESTwithout <realm-name> element.
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
CLIENT-CERT requires client to send a certificate as CLIENT-CERT specifies that authentication should be done using client's SSL certificate; without the certificate you will get an error:

We will see CLIENT-CERT based authentication in detail later.