The Carbon Java Framework  

The Carbon Security Module

Security 1-2-3

Printer Friendly Version

Author: Jordan Reed (jreed at sapient.com)
Version: $Revision: 1.4 $($Author: araman $ / $Date: 2003/05/05 07:47:01 $)
Created: February 2003

Overview

This document is meant to give an engineer unfamiliar with the design and implementation of security in a J2EE environment an overview of how to use the J2EE security model and Carbon security services and features.

J2EE Security

Introduction

J2EE defines a robust groundwork for security within applications. Teams designing and building a J2EE application should take the time to understand what is provided by the J2EE model and how to use it as the basis for their application-specific security service. Choosing to implement a security service separate from the one J2EE provides will decrease the security of your application and forego the time-saving security options provided by J2EE itself, the application server, and 3rd-party utilities.

The Sun J2EE Tutorial provides an overview of J2EE security at: http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Security.html

At the heart of the J2EE security model are the concepts of Principals, Roles and Resources.

Principal - ( java.security.Principal ) Represents an entity in the system. Principal is most often used either to represent an individual user or a group of users ( java.security.acl.Group ). In a J2EE system Principals are usually identified by their login name to the system.

Role - A logical user concept that will be granted permissions on various resources in the system. An "administrator" role might be granted access to the administration section of the site.  Roles do not have to be restricted to actual users of the system. For example, an "order-processor role" might be given to engines running on the back-end of the system that can call order processing EJBs.

Resource - Logical items in the system that users will attempt to access and perform actions on. In a J2EE system the most common resources are JSPs, Servlets, EJBs, etc.

These concepts tie together in J2EE security in the following paradigm:

  • A user is a Principal and is in a Group (a specialized Principal that is a collection of other Principals)
  • A Principal (usually a Group) is assigned to a Role
  • A Role is given access to a resource

Here's an example:

  • A User, identified by "jreed" is in a Group called "Production Support Team" that is responsible for maintaining a web site.
  • The Group, "Production Support Team" is assigned to the role "Web site Administrator"
  • The Role, "Web site Administrator" is given access to all administration web pages on a site.

It is important to remember many of these mappings are many to many. "jreed" could be in multiple groups in the system. He may also be in a "Customer" group or "Supplier" group. Groups be assigned to multiple roles. Roles can contain multiple Principals (the use of Principals is important. Roles can contain both Users and Groups which are both Principals).

Declarative vs. Programmatic Security

Security in the J2EE model is separated between declarative security and programmatic security.

Declarative security is the process of declaring security conditions inside of deployment descriptors and allowing the application server to manage the enforcement of those requirements.

Programmatic security is the process of a project team writing Java code that retrieves the currently authenticated user and performs project-specific authorizations for that user beyond the scope of J2EE-provided security.

Project teams are always required to write programmatic security on top of declarative security to protect resources the declarative security model misses. Since the declarative security model protects logical J2EE components, projects need to write programmatic security to protect business components and data objects.

Declarative Security will allow a project team to:

  • Restrict URL's to only be accessible to Principals with given roles (e.g. "/admin/*" is restricted to the "administrator" role)
  • Restrict URL's to only be accessible by various protocols (e.g. "/customer/*" is restricted to only be accessible via HTTPS)
  • Restrict Servlets to only be accessible by Principals with given roles (e.g. "SiteShutdownServlet" is restricted to the "god" role)
  • Restrict individual methods on EJBs to only be accessible by various Principals with given roles (e.g. "PurchasingEJB" is restricted to the "customer" role)
  • Assign a login page to automatically display to the user when she requests a restricted page, but is not yet logged into the system.

Declarative Security will NOT allow a project team to:

  • Restrict URL's based on URL parameters (e.g. "/showPage.jsp?type=1" is restricted to the "customer" role, but "/showPage.jsp?type=2" is restricted to the "admin" role).

Web Resources and Login

The first step in the security of an application is logging in to the system to identify the Principal accessing it. This example will go over the login process from a web application (thick client apps logging in directly to business layer are handled differently and can be read about in the J2EE Security Tutorial ).

Login is defined inside the web.xml deployment descriptor used in the application. It involves restricting a portion of the site to a specific role, and then defining what login technique the application server is supposed to use when a user attempts to access that restricted portion of the site. When unauthenticated users attempts to access a restricted page, they are automatically presented with the login page (this is called contextual or passive login). An authenticated user with the proper rights will see the page without issue, and a user without those rights will be presented with a security error which can be mapped to a project-specific page.

web.xml

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<!-- ... -->
<!--
Define the security constraint. This will limit the /admin/* portion of the application
to only be accessible to users within the "admin" role. When an unauthenticated user attempts
to access this section of the site, they will be automatically presented with the login
page.
-->
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<!-- Define the context-relative URL(s) to be protected -->
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<!-- Define the roles that are allowed to access this URL with the given methods -->
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
<!-- Transport guarantee could be used to guarantee an HTTPS protocol -->
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>

<!--
Define the method for authenticating a user when requesting a restricted page.
Methods include BASIC (the simple pop-up dialog), FORM and CERTIFICATE.
-->
<login-config>
<auth-method>FORM</auth-method>
<!--
Application servers may have multiple realms a user can authenticate against.
The most common case would be if there are multiple applications running,
each authenticating against a different user store, this could be handled
through multiple realms on the application server.
-->
<realm-name>Default Realm</realm-name>
<form-login-config>
<!--
This is the location of the page that will be presented to the user by the
application server upon the first request of a restricted page.
-->
<form-login-page>/login/login.jsp</form-login-page>
<!--
This is the location of the page that will be presented to the user by the
application server if the name/password entered on the login page do not
validate against the user store. Notice that the URL given here is a struts
action which could do various security processing (such as locking out
a user after three failed logins). It can also server side forward back
to the login page, which is popular behavior for most sites.
-->
<form-error-page>/security/securityError.do</form-error-page>
</form-login-config>
</login-config>

<!--
Finally a list of all security roles in the application must be given.
-->
<security-role>
<description>Capable of administrating the site</description>
<role-name>admin</role-name>
</security-role>
</web-app>

Now when unauthenticated users request any page under the /admin/ path in the application, they will be presented with the /login/login.jsp page. This page is used to submit a login request back to the application server that will authenticate the user.

/login/login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Example - Login Page</title>
</head>
<body>
<h1>Login Please</h1>
<%--
The form must post to the action of "j_security_check". This is a special
URL recognized by the application server as a request into the security
authentication service that it provides.
--%>
<form method="post" action="j_security_check" >
<table border="0" cellspacing="5">
<tr>
<th align="right">Username: </th>
<%-- The username field must be "j_username" --%>
<td align="left"><input type="text" name="j_username"></td>
</tr>
<tr>
<th align="right">Password:</th>
<%-- The password field must be "j_password" --%>
<td align="left"><input type="password" name="j_password"></td>
</tr>
<tr>
<%-- The form can be submit in anyway, so long as it posts to the proper place. --%>
<td align="right"><input type="submit" value="Login"></td>
<td align="left"></td>
</tr>
</table>
</form>
</body>
</html>

Passive vs. Active Login Screens

The J2EE login concept is built around passive logins. Passive logins means that the user requests a protected page, is presented with login, and is then shown the original page they request. No business logic is needed to determine where to take the user after login, because it was the users request to a page the initiated the login sequence.

Active login occurs when the site presents a way for the user to specifically request the login page. J2EE does not directly support the concept of active login, but the process is not difficult to make it support such a procedure. Below describes the procedure in Struts terminology, but the model works in any presentation framework (or none through the user a Servlet or JSP instead of the Struts action).

  1. Create a LoginAction and restrict its URL to a role that all users in the system have access to
  2. Link to this LoginAction as the login page in the application
  3. When the user clicks on this action, they will not be presented with this protected action, but the with actual login page specified in web.xml
  4. Upon successful authentication, the application server will forward the user to the LoginAction
  5. The LoginAction will have access to the Principal object and can redirect the user to the appropriate after-login page.

EJB Resources

Restricting of EJB resources is similar to restricting Web resources and done within the EJB deployment descriptors on a method-based system.

ejb-jar.xml

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN'
'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'>

<ejb-jar>
<enterprise-beans>
<!-- ... List all the beans here ... -->
</enterprise-beans>
<assembly-descriptor>
<security-role>
<!--
Just like in web.xml, each security role must be listed. These roles will be
mapped back to principals in the application in the application server specific
deployment descriptors.
-->
<description>Capable of administrating the site</description>
<role-name>admin</role-name>
</security-role>
<method-permission>
<!-- List the roles that this permission applies to -->
<role-name>admin</role-name>
<!--
List the methods that the permission applies to. In this case access has
been given to all methods on the administrator ejb
-->
<method>
<ejb-name>org.examples.securitydemo.AdminEjb</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
</assembly-descriptor>
</ejb-jar>

Programmatic Security

Programmatic Security is entirely defined within various methods of the J2EE API.

These methods, while somewhat useful, do not provide robust abilities to check a user's ability to access specific data objects or functions within the system. For example, in a banking application if a user's account number is 12345, there is no way in this model to test that. Instead, the business logic of the application must determine the accounts a user has access to given her principal name.

J2EE Conclusion

This example gave a brief overview of how to use the provided APIs in the J2EE security model. There are many pieces of functionality that are still missing to be able to build a robust, secure J2EE application. Carbon provides services that solve many of the generic problems (discussed in the next section) but many are application-specific.

Framework Services

Carbon provides services built to compliment the standard J2EE security model and fill in some of the missing pieces in application security. Carbon services are designed around providing the plumbing for the application, but the application-specific business code and logic is still left in the hands of the project team to design and implement.

User Manager

The Carbon User Manager service provides a generic API for accessing and managing a store of users. Most J2EE applications will store their list of users and the users' association to groups inside either a relational database or an LDAP server.

The User Manager provides a programmatic security API similar to the J2EE programmatic API. In fact, when the User Manager is fully integrated with the application server (explained later), calls to the standard J2EE security API will pass directly into the User Manager APIs. This means that the application can simply pass around a reference to the current principal, and using Carbon's User Manager service be able to execute similar programmatic security checks without the need to have a reference to an HttpServletRequest or EJBContext object.

For additional information on the User Manager service, please see specific documentation:

Application Server Integration

Carbon provides adapter classes that allow application servers to integrate with the Carbon User Manager service. This means that authentication checks and checks of a user's membership in roles will go through the same User Manager system that programmatic application security goes through. It unites all parts of security and user management in the application to a single API.

For additional information on the Application Server Adapters, please see specific documentation:

Project Team's Responsibility

Protecting Data Objects

Applications generally contain a large collection of data objects that are restricted. For example, a banking application would have all of the users' accounts stored inside its database. These are items which must be restricted, but are not good candidates for the standard J2EE APIs or Carbon User Manager APIs.

Restricting Data Objects should be done at the manager level programmatically. When a call is made into the business layer, typically through a stateless session bean, the current user's Principal object is available through the EJBContext. This should then be passed to the account manager object responsible for knowing which are the correct accounts to return for the given Principal:

findAccountsByPrincipal(user : Principal) : Collection - Returns the collection of all accounts the Principal is associated with.

Components on HTML Pages

It is often desirable to have HTML pages customized based on the current user's role and privilege. Some level of this can be done using the two Struts logic tags of <logic:present> and <logic:notPresent>. These tags can be used to optionally display sections of html based on the presence of a Role in the authenticate user's memberships.

Beyond this simple logic, custom tags and other logic must be used to provide html customization to the end-user.


Additional Questions

What is the Role of JAAS?

Java introduced the Java Authentication and Authorization Service (JAAS) to create a standard way to handle a user's security in an application. The JAAS API can be downloaded as an extension to Java 2, and is part of the standard packages in J2SE 1.4.

JAAS has a high level of integration with J2SE, but has not yet acheived that level with J2EE. Currently, there is no standard to tie a J2EE Container into a JAAS security system. Application servers are moving towards using JAAS' authentication APIs (the LoginModule) but are still not using JAAS' authorization APIs.

Weblogic 7 has begun using JAAS to support all of its security services. For Carbon's User Manager service to integrate with Weblogic 7 requires, as one step, the creation of a JAAS Login Module that allows login against the Carbon User Manager service. The Weblogic 7 Adapter calls into this JAAS Login Module, which in turn calls the Carbon User Manager Service.

Appendices

Definitions

Term Definition
Principal A description of a unique entity in the system. This can either be a user or a group.
Credential A piece of information used by a Principal to prove his identity. Common credentials include passwords and certificates.
Declarative Security Security restrictions defined against components of an application by declaring them in configuration files.
Programatic Security Security restrictions defined against process-flow inside of a component through code that checks the user and alters process flow accordingly.
Passive Login
A login dialog is presented to the user after the user has requested a restricted resource. Upon successful authentication, the user is taken to the requested resource.
Active Login
A user specifically requests to login to an application. Upon successful authentication, the application must determine the proper destination to take the user to.
Trust Relationship A relationship where one object trusts the security of another. Used to allow the user to sign-on with one object, and then not need to pass a credential to another object.

References

Reference Location
J2EE Specification v1.3 http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf
JSR 115 - Java(TM) Authorization Contract for Containers http://www.jcp.org/jsr/detail/115.jsp
Java(TM) Authentication and Authorization Service (JAAS) http://java.sun.com/products/jaas/
J2EE Tutorial - Security http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Security.html
WebLogic 6.1 - Introduction to WebLogic Security http://e-docs.bea.com/wls/docs61/security/intro.html
IBM WebSphere V4.0 Advanced Security Edition Redbook http://www.redbooks.ibm.com/redbooks/SG246520.html
Tomcat 4.1 - Realm Configuration http://jakarta.apache.org/tomcat/tomcat-4.1-doc/realm-howto.html
ONJava - J2EE Form-based Authentication
http://www.onjava.com/pub/a/onjava/2002/06/12/form.html

Copyright © 2001-2003, Sapient Corporation