This month's article is the first in a two-part series on J2EE security. In Part 1 we'll discuss basic J2EE security. Part 2 will provide you with a model to set up and deploy a functioning security-enabled application. Resident J2EE security guru, Chris Siemback, has been kind enough to join me in coauthoring this series to contribute in-depth examples of J2EE security at work.
Our discussions will cover securing both Enterprise JavaBeans (EJBs) in the business and data layers as well as JavaServer Pages (JSPs) and servlets in the web layer of a J2EE application.
J2EE Security Overview
Understanding the strong suits and weaknesses in the J2EE security model will help you determine the right security architecture for your application. A basic overview of J2EE security will help you compare its qualities to your security requirements. Let's come to grips with a few terms we'll see in the discussion that follows:
With so many choices in security domains, how do you choose which one to use in your enterprise application? Numerous factors are involved including politics, corporate standards, and features such as the ability to modify the realm and for the realm to cache information.
A principal is an entity that can be authenticated in an enterprise application. The data and the content required to be authenticated may be different from implementation to implementation, but a principal is generally authenticated by a username and password combination.
- Security Policy Domain
A security policy domain, commonly called a realm or, just, security domain, is simply the implementation of a store containing authentication and authorization information and the enforcement of policies on this information as defined by a security administrator. Security domains are typically repositories where users, groups, permissions, and secured resources are stored. In other words, the realm contains the usernames, passwords, and roles that the container uses to authenticate and authorize user requests. A realm may be based on LDAP, UNIX, database, and NT security stores, or it may simply be XML documents that are read by the application server.
For instance, politics and technology often govern standards in the organizations with which we work. If an organization has standardized on NT, you may choose to leverage the existing NT security.
For large-scale applications, you should ensure that your implementation of a J2EE security domain has at least the ability to add, remove, and modify users, roles, privileges, and secured resources to and from the realm without having to shut down the server. Some implementations are statically loaded and do not allow reloading of security information. However, this forces downtime to reload modified information, which is generally not acceptable in today's online applications.
Also, a great feature to have in your realm is the ability to cache security information. Although it may change (as mentioned above) this information is generally static, and a high-performing application needs the ability to cache commonly used information at the application server level rather than retrieving it from a persistent store with each request.
Now that you have a handle on the security vocabulary we'll be using, let's look at how J2EE security allows the authentication and authorization of principals within a security domain, providing access to secured resources such as Web components and EJBs.
A credential either contains security attributes or refers to attributes for a principal. A credential is used to grant access to other secured services; thus it's passed along to each service accessed by the principal. If security attributes are not passed along, they may be retrieved from a trusted third party storing the information required for authentication and authorization.
- Authentication and Authorization
When you attempt to access restricted resources, the container is responsible for both authenticating and authorizing the request based on your credentials. Authentication is the process of verifying who you are. Authorization is the step made after authentication that verifies whether or not you may use a secured resource.
Characteristics of J2EE Security
There are two main characteristics of J2EE security: it's role-based rather than user-based (object level), and declarative rather than code-based. J2EE security is designed to be a role-based, declarative approach to securing applications and resources through the use of security domains.
Since mapping is performed at the deployment of the component, the component is portable across compliant J2EE servers such as WebLogic Server (www.bea.com) and iPlanet Application Server (www.iplanet.com).
- Role-based Security
J2EE security authorizes access to resources based on the role of the user. An example of a role would be a member or system administrator. Once users have been authenticated (e.g., they exist in the security domain), they'll begin to access various resources while performing their business tasks. This will result in any number of security checks by the J2EE server against the credential (e.g., permissions) of the user with respect to the "role" the user assumed at login.
The ability to perform object-level security (security on a per-user basis) is often required in sophisticated enterprise applications. However, role-based security is incapable of performing object-level security because roles relate to a "group" level rather than focusing on an individual. For instance, there's no way to ensure that the user "John Doe" can view/modify his own employee records, but not other employee records. You could declare that users in the department manager role can view/modify all employee records in their department, however. If your application requires object-level security, be sure to architect it into your solution.
- Declarative Security
The J2EE platform strives for portability across compliant servers. To this end, J2EE stresses the use of declarative security in Web applications (.wars) and EJBs, rather than promoting coding of security logic. Declarative security allows the J2EE server to intercept requests to access secured resources and perform authentication and authorization to use the service. No coding is involved on your behalf. However, the deployment of the component involves the extra step of determining which roles have the right to use a resource and then mapping these roles to the appropriate services.
Not only does J2EE support declarative security, it also provides an API into the security principals in the domain allowing programmatic checks. This feature is neither as portable, nor as configurable as declarative security, however, and should be used with caution.
Securing Web Resources
All J2EE products are required to support a single sign-on in the web tier, so you shouldn't have to log in multiple times for different applications on a site. Furthermore, it specifies that authentication occurs only if a user attempts to access restricted resources. This is described as "lazy authentication," which means you may freely access web-based resources if no security restrictions are placed on them. If you later attempt to access restricted portions of the site, the server must use one of three methods to authenticate the user:
For more information on web-based security, see the Servlet 2.2 specification. It can be downloaded at www.javasoft.com/products/servlet/download.html.
- HTTP basic authentication
HTTP basic authentication is the security method supported by the HTTP protocol. This is the familiar browser pop-up window that requests a username and password. For instance, you may have encountered it the last time you tried to hack your friend's secured site. Upon receiving the username and password, the Web server authenticates the username against the security domain. Note that basic authentication is not a secure method of sending credentials. Adding SSL can alleviate this concern, but there's no control of the look and feel of the browser-generated pop-up window.
- HTTPS Authentication
HTTPS is HTTP over Secure Sockets Layer (SSL). SSL encrypts the data being sent between the client and the Web server using a "public/private" digital key scheme. This means that although someone may be able to intercept the data being transmitted, he or she will not be able to decrypt the information without the private key. This method of security is often used with applications that require credit card numbers, for example, purchasing a book at Amazon.com. This is all done automatically by the client and the server and doesn't require any input from you, the user.
- Form-Based Login
Form-based authentication allows developers to create customer login pages for their users. When you attempt to access restricted resources, the custom login page is displayed. The credentials you provide are sent back to the server (preferably over SSL) and verified against the domain. If you have authorization, you're granted access to the resource, otherwise, a custom "failed login" page is presented.
In the spirit of J2EE's declarative security, the EJB architecture discourages (but does not prevent) the practice of hard-coding security logic in EJBs. Instead, EJB's security model allows developers to place restrictions on bean methods contained within the remote and home interfaces through its deployment descriptor.
During the assembly of an EJB, the application assembler is responsible for defining security roles for an application. This entails bundling sets of permissions into logical groups that restrict component access at the method level. Next, the deployer is responsible for mapping the defined security roles to groups within the enterprise's security domain. In many cases, the same individual performs these two roles.
During method invocation on an EJB component, the container intercepts the method call, enforcing the security restrictions defined during deployment for the EJB. The EJB container will allow a user to execute a method only if the caller's principal is contained within one of the defined security roles. Furthermore, as EJBs invoke methods on other EJBs in the system, the security context is passed along to each component. While this enables seamless security checks across the EJB layer, there's a performance penalty encountered while checking security on each method call.
For more information on EJB security, see the EJB 1.1 specification. It can be downloaded at www.javasoft.com/products/ejb/docs. html.
J2EE Security: Putting It All Together
In the previous sections, we reviewed how each layer in a J2EE application can be secured, but how do web components and EJBs work together to provide a unified, single sign-on across all layers of your architecture? Figure 1 depicts a web client accessing restricted resources such as JSPs, servlets, and EJBs. As you can see, each layer in the J2EE architecture (Web server and EJB container) provides its own authentication against the security domain.
The web server first authenticates the user against the security domain, then confirms that the credentials supplied match to a principal (user) within the security domain. If the user doesn't exist, the authentication fails and the request for the specified resource is denied.
If authentication is successful, the server authorizes the request to access the secured resource, verifying that the user has been given adequate permission to use the resource. If the user has the required permissions for the resource, then the request is granted access to utilize its services; otherwise the server will deny the request. Notice that the credentials provided to the web server are propagated to the EJB, providing seamless integration. In both cases, the container will enforce the security restrictions based on the deployment descriptor for the component.
J2EE security can be used to secure resources in a portable fashion. Because it's declarative in nature, no coding is necessary to implement it in either the EJB layer or the web tier, providing transparent security for the developer. This keeps both your web component and EJB code focused on presentation or business logic, and enhances portability across different servers. Furthermore, it lets businesses use any type of data store as a security policy domain, allowing them to leverage any existing security implementations they currently have.
J2EE security was designed to provide a portable and flexible solution. however, it's important to be aware of some of the limitations. If your application(s) requires a very fine-grain level of security, you may need to add programmatic security. This obviously reduces the portability of your code and opens up possible security holes.
Next month in EJB Home, we'll walk through a sample application based on BEA's WebLogic Server that demonstrates the concepts described here. We'll create a relational database security domain, then construct a secured web-based application that communicates with EJBs. See you next month!
Jason Westra is CTO at Verge Technologies Group, Inc., a Java consulting firm specializing in e-business solutions with Enterprise JavaBeans.
Chris Siemback, an Enterprise Java consultant at Verge Technologies Group, Inc., specializes in Web-based EJB
applications, various development