Java EE 6 RI was released few weeks ago….I am bit late to have my first look
Without a doubt, the new Web container security enhancements are very compelling for any budding or experienced Java developer working on Web applications. The Java EE 6 has unveiled several new security features with ease of use and targetted for simplified Web application security deployments. Based on Servlet 3.0 specification, the Java EE 6 Web applications can take advantage of an enriched set of programmatic and declarative security features and Security annotations previously available to EJB 3.x applications. Also, the deployed Web applications/Web Services can use JSR-196 based pluggable authentication/authorization modules (based on SOAP Web Services) that can be configured as part of the Servlet container.
The newly introduced Java EE 6 programmatic security features for Web applications are represented by the following methods of HttpServletRequest interface:
1. authenticate()
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyAuthServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=UTF-8″);
PrintWriter out = response.getWriter();
try {
//Launch the BASIC authentication dialog
request.authenticate(response);
out.println(“Authenticate Successful”);
} finally {
out.close();
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
}
2. login() and logout ()
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MySecurityServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=UTF-8″);
PrintWriter out = response.getWriter();
try {
String myUsername = request.getParameter(“UserName”);
String myPassword = request.getParameter(“Password”);
try {
request.login(myUsername, myPassword);
} catch(ServletException ex) {
out.println(“Login Failed” + ex.getMessage());
return;
}
} catch (Exception e) {
throw new ServletException(e);
} finally {
request.logout();
out.close();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
}
The above code assumes the authentication is configured to BASIC by setting the login-config element in web.xml. If the authentication is the successful, the Web application can take advantage of the following methods in the HttpServletRequest interface to identify the remote user, role attributes and to perform business logic decisions.
3. getRemoteUser()
4. IsUserInRole(..rolename..)
5. getUserPrincipal()
Here is my sample code that I tested it on Glassfish v3 (Developer Sample):
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import javax.annotation.security.DeclareRoles;
//Annotation for defining the Servlet name and its URL pattern
@WebServlet(name=”MySecurityServlet”, urlPatterns={“/MySecurityServlet”})
// Annotation for declaring roles
@DeclareRoles(“securityguy”)
public class MySecurityServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html;charset=UTF-8″);
PrintWriter out = response.getWriter();
try {
String myUsername = request.getParameter(“UserName”);
String myPassword = request.getParameter(“Password”);
try {
request.login(myUsername, myPassword);
} catch(ServletException ex) {
out.println(“Login Failed” + ex.getMessage());
return;
}
out.println(“The authenticated user is in Role: ” + request.isUserInRole(“securityguy”));
out.println(“The authenticated remote username: ” + request.getRemoteUser());
out.println(“The authenticated Principal name: ” + request.getUserPrincipal());
out.println(“The authentication type: ” + request.getAuthType());
} catch (Exception e) {
throw new ServletException(e);
} finally {
request.logout();
out.close();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
}
To test the code, it is assumed that you have the Java EE runtime deployment descriptor include the appropriate role mapping that associated the user with the specified role-name.
With Servlet 3.0 implementation, we would able to use standard Java annotations for declaring security constraints as equivalent to those defined in a standard Web deployment descriptor (web.xml). With Security annotation you should able to define roles, access control to HTTP methods, transport-layer protection (for enforcing SSL/TLS). To make use of security annotations in Servlets, Servlet 3.0 has introduced @ServletSecurity annotation to support defining security constraints.
The @ServletSecurity annotation allows to define the security constraints as its fields:
Here is a quick usage scenario of @ServletSecurity annotation (Developer Sample):
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.annotation.security.*;
@DeclareRoles("customer","guest")
@ServletSecurity(@HttpConstraint(rolesAllowed={"customer"}))
public class MyHelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("Hello World");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Hello World");
out.close();
}
}
Sometimes, it’s the small things that make even complex things much easier. Way to go…Java EE 6 !
Here is couple of references, you may consider to explore Java EE 6:
Glassfish v3/Java EE 6 Sample Applications
Enjoy
Yes, the demand for rich clients and rich-client-like Web applications are definitely overwhelming for its look and feel performance. When we think of rich clients over Web, we often think of applets as a solution in
the first place and we forget to consider other promising options like Java Web Start (JWS) and other Web 2.0 interfaces via Ajax and Java Server Faces (JSF). Having said that, I would like to explore your specific concerns related to applet sandbox vulnerabilities!
In most cases I found the common compromises are due to browser-specific vulnerabilities and missing access control policies to its SecurityManager for restricted execution and access to its local file system. Enforcing stringent access control policies (using a policy file) and usage of signed applets are often considered to be best practice options for deploying secure applets. The Java 2 platform introduced the notion of signed applets, which allows signing an applet to ensure an applet’s origin and its integrity are guaranteed by a certificate authority (CA). The signed applet can be trusted to run with the permissions granted in the policy file defining the access control privileges for its execution and local resources. More importantly, it is important to verify your target client browser for any known security vulnerabilities related to Java applet plug-in and its runtime environment.
Although applets are very compelling in a Web environment, I would suggest considering JWS and JSF as two alternative solutions to building applets. JWS is a full-fledged application that allows Java rich-client applications to be deployed, launched and updated from a Web server. The underlying technology of JWS is Java Network Launch Protocol (JNLP), which provides a standard way for packaging and provisioning the Java application (as JAR files) and then launching them over a network. From a security perspective, JWS applications run outside a Web browser using the sandbox features of the local Java Runtime Environment (JRE). JWS also allows defining security attributes using a JNLP descriptor for client-side Java applications and their access to local resources such as file system access, making network connections and so on. JWS also support the use of signing JAR files (similar to applets) in order to verify the application origin and its integrity so that it can be trusted before it is downloaded and executed on the local machine.
JSF is another promising Web client presentation solution runs using a server-side J2EE environment similar to Java Server Pages (JSPs) and servlets, augmented with the power of rich-client like UI components. With JSF, developers can add Asynchronous JavaScript and XML (Ajax) functionality by inserting specialized AJAX/JavaScript technology code. JSF adopts the J2EE Web container security mechanisms to enforce security and controlled access to operations and their underlying resources. The Web container security features include authentication, authorization, secure session handling, transport-layer security, single-sign on access and so forth. For implementation specific details, I would suggest referring to Core Java Server Faces in conjunctiion with Core Security Patterns for supporting design patterns and best practices.