Sun Java Solaris Communities My SDN Account Join SDN

Article

Sun Java System Application Server 7 Access Control Guide

By Jyri Virkki and Marina Sum, January 8, 2004  

Although implementing access control in Sun Java System Application Server 7 (formerly Sun ONE Application Server 7 and hereinafter called Application Server 7) on the Java 2 Platform, Enterprise Edition (J2EE) is relatively straightforward, ensuring that all the configurations are correct can be laborious and even problematic. This guide serves as a starting point for learning the access-control capabilities and configurations for your application and the Application Server 7 instance. It contains the following major sections:

In addition to reading this guide, experiment with the samples included with Application Server 7 to become familiar with its functionality. Also, consult the reference material cited throughout this guide.

Note - This guide is not a substitute for the Application Server 7 product documentation or the specifications for Servlet 2.3 and Enterprise JavaBeans 2.0 technologies. For a thorough understanding of J2EE development with Application Server 7, read those documents--they are the authoritative source of the information in this guide.

1. Overview of Access Control

Access control consists of two main components: authentication and authorization. Though related to each other, these are two distinct operations that occur in Application Server 7 at separate stages, independently of each other. Authentication is a process in itself. Authorization, often a consumer of the output from authentication, is another process. This differentiation is frequently the source of confusion during the initial stage of configuring access control.

1.1 Authentication

Authentication is the process of validating a user from the credentials that the user presents to the server. Those credentials can be a combination of user name and password or they can be an X.509 certificate. The result is either success or failure.

On success, a security context is established within Application Server 7 associated with that request--a context that contains the user's identity for the duration of that request. The application or Application Server 7 can consult that context whenever information on user identity is required, for example, during authorization. By default, when the request terminates, the security context disappears. However, with additional mechanisms, such as HTTP sessions and Single Sign-On (SSO), the context can persist across multiple requests.

Because authentication is separate from authorization, a user who successfully authenticates to Application Server 7 can fail the authorization logic, resulting in a denial of request.

Logically, authentication occurs in two phases:

  1. Interaction with the client, usually a browser, to obtain the necessary credentials (user name and password or an X.509 certificate), a step that's implemented by Application Server 7

  2. Validation of the credentials, a step performed by a pluggable component, called a realm

1.1.1 When Is Authentication Performed?

Application Server 7 supports two types of authentication, as described below. Depending on the type in use, the timing of the authentication event varies.

  • Container-managed authentication -- This type of authentication applies when the container (Application Server 7 in this case) triggers and handles the event, of which the application has no knowledge. This is the recommended approach for all J2EE applications because no hardcoding of authentication logic is required in the application.

    Authentication occurs when Application Server 7 determines that user identity is required to satisfy a request. Because it supports "lazy authentication," Application Server 7 can enforce authentication only when the user is requesting a resource that is protected by one of the access-control rules defined in the application's deployment descriptors. For details, see "Implementation of Access Control in J2EE Applications."

    If Application Server 7 determines that authentication is required, it prompts the user for credentials. The ensuing process depends on which authentication method applies to the request (see the subsection after next).

  • Application-managed authentication -- This type of authentication applies when the application itself triggers the event and supplies the necessary credentials. This mechanism, rarely necessary, reduces the portability of the application and is not recommended. Occasionally, however, special-purpose applications must handle authentication directly. The programmatic login interface in Application Server 7 supports this approach.

    With programmatic login, the application code, not Application Server 7, controls the timing of the authentication event. That means authentication must occur when the application is running and not during the processing of the request by Application Server 7, which is valid for container-manager authentication only.

1.1.2 Where Is Authentication Performed?

Rather than validating user credentials internally, Application Server 7 delegates that task to the default or current realm--a pluggable module that performs authentication checks and returns the result (success or failure) to the server itself.

1.1.3 What Are the Authentication Methods?

Application Server 7 supports the following authentication methods:

  • For HTTP requests -- HTTP BASIC authentication, FORM authentication, or Secure Socket Layer (SSL) authentication, called CLIENT-CERT in the Servlet Specification

  • For Internet Inter-Object Request Broker Protocol (IIOP) requests -- Authentication of user name and password or SSL client certificate

    Processing of the authentication method is handled by Application Server 7. Realms do not interact with remote clients (usually browsers). The default realm simply receives the credentials, such as the user name and password, that were collected from the client by Application Server 7 through authentication.

1.2 Authorization

Authorization, the process of deciding whether to allow a request to run or to reject it, occurs when a resource protected by access control rules is accessed. On the J2EE platform, authorization is based on roles. To effect access control while developing an application, you declare which parts of the application require special authorization for access and define the roles associated with each of the access-controlled areas. If the user who makes an access request belongs to any of the roles, Application Server 7 authorizes the request; otherwise, it rejects the request.

In J2EE applications, the default mode is to always grant access unless restricted. That is, if a resource has no applicable access-control rules, everyone can access it. Otherwise, access is granted contingent on a match of the roles.

For details on the configuration procedures, see the section "Implementation of Access Control in J2EE Applications."

1.2.1 When Is Authorization Performed?

As with authentication, Application Server 7 supports both container-managed and application-managed authorizations.

Container-managed authorization occurs when Application Server 7 determines that, according to the access-control configurations, the current request is potentially restricted. To prevent unauthorized requests from consuming more resources than necessary (for example, filters, which are run after authorization), Application Server 7 triggers authorization early in the request process.

1.2.2 Where Is Authorization Performed?

Application Server 7 performs authorization internally according to the access-control rules that are declared in the application descriptors.

1.3 Authentication Realms

Recall that a realm is a pluggable module that validates user credentials. It is the interface between Application Server 7 and the user repository being used by that server instance.

Note - A point of clarification: Realms interact with the user repository only, not with remote clients. Realms play no part in establishing or maintaining the security context within Application Server 7. Also, realms are not responsible for or aware of the authorization factors, such as role names and role mappings.

Authentication realms are responsible only for the following tasks:

  • Maintain a list of users or, if the list is maintained elsewhere, for example, a Lightweight Directory Access Protocol (LDAP) directory, the procedure on how to look up users.

  • Maintain the information on validating user passwords or the knowledge of delegating the authentication elsewhere, such as an LDAP directory.

  • Maintain an associated list of zero or more group names for each of the users or, if the list is maintained elsewhere, for example, in an LDAP directory, the procedure on how to look up users.

  • Return a true or false value to indicate the validity of the association between a user name and a password.

  • Return a list of the groups that are associated with a user name.

Out of the box, Application Server 7 affords four built-in realms; you can choose to adopt one of them for your application:

  • File realm -- The file realm, a simple user repository based on lightweight files, is not intended to scale to a large number of users. The user-related information (name, hashed password, and group membership, if any) is stored in a flat file called keyfile, on disk. By default, keyfile is located in the config directory of the server instance. Thanks to its simplicity and convenience, the file realm is especially suitable for development and testing. It's also the fastest realm because all the authentication details are stored in memory within the Application Server 7 process.

  • LDAP realm -- The LDAP realm interacts with a remote LDAP server for user authentication and group membership.

  • Solaris realm -- The Solaris realm delegates authentication to the Password Authentication Module (PAM) stack, which is configured on the Solaris Operating System on which Application Server 7 is running. This realm is supported on the Solaris 9 OS and later versions.

    A limitation of the Solaris realm is that if the underlying PAM stack requires root access--for example, if it makes use of /etc/shadow-to access that stack, the Application Server 7 server instance must run as root.

  • Certificate realm -- The certificate realm supports authentication of SSL and Transaction Level Security (TLS) client certificates through the user's X.509 certificate. This realm does not authenticate credentials that are based on user names and passwords, nor does it support mappings or other operations, except for global group assignments. Application Server 7 does not expose interfaces for plugging in custom (X.509-based) certificate realms.

1.3.1 Configuration Procedure

To configure realms, edit the security-service element in the server.xml file. Here is an example of a default configuration:

<auth-realm name="file"
classname="com.iplanet.ias.security.auth.realm.file.FileRealm">
    <property name="file" value="/install_path/domains/domain1/server1/config/keyfile"/>
    <property name="jaas-context" value="fileRealm"/>

</auth-realm>

Every realm must contain a name and the name of the Java class that implements the realm. The realm's name attribute is a unique identifier in server.xml to specify which realm to use. You must also specify that information in the security-service element, for example--

<security-service default-realm="file" ... >

Optionally, every realm can have property (name-value) pairs that represent additional configurations required by that particular realm type. The four realm types support mostly different properties. For example, the file realm requires a property called file, whose value contains the path to keyfile, which the realm reads for user information.

The jaas-context property, common to all the realm types except the certificate realm, defines the name of the Java Authentication and Authorization Service (JAAS) login context used by the realm in question. The login context named here must correspond to an entry in the login.conf configuration file.

For more details on configuring realms, see these sections in Application Server 7 Developer's Guide:

1.3.2 Custom Realms

The four authentication realm types in Application Server 7 do not cover all possible scenarios; enterprises often have special requirements for interactions with their authentication service. To meet those needs, Application Server 7 supports custom realms.

You can find a sample of Application Server 7's custom authentication realm in the following directory within your installation:

samples/security/realms/rdbms/src/samples/security/jdbcrealm/

To create a custom realm, you must build a login module and a realm. The sample includes a basic implementation of both: JDBCLoginModule and JDBCRealm, which can serve as templates for your implementation. You need only revise the internal authentication logic to perform the steps you require. Follow these steps:

  1. Copy JDBCLoginModule and JDBCRealm to a working directory.

  2. Rename the classes and package as desired, for example, com.xyz.MyLoginModule and com.xyz.MyRealm.

    Important: Do not modify the inheritance of the classes and do not override any inherited methods, except as described in the following steps. Avoid relying on the implementation of the parent classes, except as noted. Otherwise, your custom realm may be incompatible with future Application Server releases.

    Feel free to delete private methods that are specific to the sample and that are of no use to your realm.

    Next, revise the logic as follows:

  3. In MyLoginModule, revise the method authenticate(), as appropriate.

    This method is invoked when a user attempts a login. If authentication fails, it throws the LoginException error.

    1. Obtain the user and password data from the _username and _password fields.

    2. Add the following statement to the end of authenticate(), where grpList is the list of groups to which _username belongs, if any:
      return commitAuthentication(_username, _password, _currentRealm, grpList);
      
  4. In MyRealm, modify the following methods, as appropriate:

    • init() -- During startup, Application Server 7 invokes this method once. The properties object contains the properties defined for this realm in server.xml. You must include here any one-time initialization required by the realm implementation. If this method returns successfully, Application Server 7 considers the realm ready to service requests. If this method throws an exception, Application Server 7 disables the realm.

    • getGroupNames(username) -- This method returns any groups to which the user belongs. Application Server 7 uses the list of group names returned by this method to evaluate group mappings.

  5. Add MyLoginModule to login.conf.

    For example--
    myRealm {
    
            com.xyz.MyLoginModule required;
    };
    
  6. Add a new auth-realm element to server.xml and specify the properties for your realm.

    Be sure to add the jaas-context parameter, which names the login context. Refer to the built-in realms for example configurations. For example--
    <auth-realm name="mycustom" classname="com.xyz.MyRealm">
            <property name="prop1" value="...."/>
    
            <property name="jaas-context" value="myRealm"/>
    </auth-realm>
    
  7. Activate the realm.

    For example--
    
    <security-service default-realm="mycustom" ... >
    
2. Implementation of Access Control in J2EE Applications

This section is a detailed procedure for implementing access control in J2EE applications on Application Server 7. The procedure consists of four phases:

  1. Designing an access-control scheme

    1-1. Decide which areas of your application--Web URIs or EJB methods or a combination of both--are controlled areas.

    1-2. Decide the granularity and the names of the roles to use for categorizing access to controlled areas.

    1-3. Assign the roles that are allowed access to each of the controlled areas.

  2. Configuring access control for applications

    2-1. For each URI from step 1-1, add a corresponding url-pattern element in the web.xml file to declare the role that can access the controlled areas.

    2-2. For each EJB method from step 1-1, add a corresponding method-permission element in the ejb-jar.xml file to declare the roles that can access the controlled areas.

    2-3. Configure the authentication method for the application.

  3. Determining and configuring realms

    3-1. Decide which authentication realm to adopt and configure the settings in the server.xml file.

    3-2. Ensure that the data for all the users who can access the application are in the database that corresponds to the realm. Add to or edit the realm database as appropriate.

    3-3. If you use group mapping, assign users to the appropriate groups.

  4. Setting site-specific application configurations

    4-1. Assign users to each of the roles from step 1-2.

    4-2. Decide whether to use direct principal mapping for the roles or group-based mapping on the basis of your decision regarding the user database from step 2.

    4-3. For every role from step 1.2, apply the appropriate security-role-mapping elements to your application based on your decisions from steps 3-1 and 3-2.

2.1 Access-Control Schemes

The default access mode in J2EE applications is open, that is, if you do not impose access restrictions, the entire application is accessible to everyone. To override the default, specify the resource areas in your application that require access control, as follows:

  1. For the Web components, list the paths within the Web context root of the application that require access control. At that time, specify the granularity of the access control.

    To restrict access to the entire application without exception, use the wildcard string /* to denote the protected area. To specify open areas and protected areas, list the path for each of the protected areas.

    TABLE 1 is an example.

    TABLE 1 - Example of Protected and Unprotected Areas in an Application
    /*.[html | jsp]
    Not protected
    /members/*
    Protected
    /schedule/*
    Protected
    /financials/*
    Protected
    /results/*
    Not Protected
     
  2. For the EJB components, list which ones to protect.

    You can list either an EJB component, in which case all its methods are protected; or certain methods in the EJB component, in which case only those methods are protected. For example--

    • The statistics enterprise bean contains numerous getter methods; however, you need to restrict access to getAverageRevenue() only.

    • The members enterprise bean contains a number of methods for manipulating member data, all of which you must protect.

      TABLE 2 illustrates how to specify that protection scheme.

      TABLE 2 - Example of a Protection Scheme for EJB Components
      statistics
      Not protected
      statistics.getAverageRevenue()
      Protected
      members
      Protected
       
  3. Decide who can access each of the protected areas.

    To maximize the portability of your application and to save maintenance overheads, do not associate the areas with specific people in your organization. Instead, associate each area with the type--or role--of the people to whom to grant access, that is, a shared trait of those folks.

    Design a role scheme in accordance with the services your application performs. A common practice is to name roles after job categories, such as managers, writers, and such. You can also partition roles according to operational tasks, such as backup or configure; or according to time shifts, such as day-operator or night-operator. These are just examples; you can partition roles along any namespace scheme you desire.

    As time passes and as your organization evolves, the user names that belong to the roles will change. For instance, the managers of today may move on to other jobs; the night operators could be different every night of the week. The roles in your scheme remain relatively stable, however.

    Note - One exception to the requirement for specifying roles: If you want to impose access control to authenticate users only before granting them access, and if all authenticated users can access all areas, then you can waive that requirement.

    TABLE 3 shows the controlled areas in a sample application in Application Server 7 and their associated roles.

TABLE 3 - Access-Control Scheme in a Sample Application
Directory or Method Protected? Remarks Roles
/*.[html | jsp]
Not protected
Open to all, no roles required.
Not applicable
/members/*
Protected
Open to all members. Since all employees and owners are considered members, this area is open to all authenticated users.
*
/schedule/*
Protected
Schedule data open to employees and owners only.
employee, owner
/financials/*
Protected
Financial data open to owners only.
owner
/results/*
Not Protected
Results data open to all, no roles are required.
Not applicable
statistics
Not Protected
Open to all, no roles required.
Not applicable
statistics.getAverageRevenue()
Protected
Open to owners only.
owner
members
Protected
Open to employees and owners only.
employee, owner
 

2.2 Access-Control Configurations in Web Modules

You configure Web modules with access-control parameters in the web.xml file.

2.2.1 Configurations for Authentication

Set the authentication method in the login-config element by specifying the value for the subelement auth-method, which supports three values, as follows:

  • BASIC -- Include a realm-name element. However, Application Server 7 does not use the value of that element to associate applications with realms. Here is an example:
    <login-config>
            <auth-method>BASIC</auth-method>
            <realm-name>Users</realm-name>
    </login-config>
    
  • FORM -- Include additional information as appropriate. Here is an example:
    <login-config>
            <auth-method>FORM</auth-method>
            <form-login-config>
                            <form-login-page>/login.jsp</form-login-page>
                            <form-error-page>/error.jsp</form-error-page>
    
            </form-login-config>
    </login-config>
    
  • CLIENT-CERT -- Here is an example:
    <login-config>
            <auth-method>CLIENT-CERT</auth-method>
    
    </login-config>
    

Application Server 7 triggers authentication if and when necessary according to the configurations for authorization.

For more information on login-config, see chapters 12 and 13 in the Java Servlet Specifications.

2.2.2 Configurations for Authorization

Configure authorization requirements in the security-constraint element, which contains two main items:

  • The request characteristics for the protected resource, which includes the namespace (url-pattern) and HTTP methods (http-method). Specify them in the web-resource-collection element.

  • The roles that are required to satisfy access control for access to be granted. Specify this information in the auth-constraint element.

If your application contains multiple protected areas, specify as many security-constraint elements as necessary.

Following are the corresponding configurations for authorization in the same sample application.

<security-constraint>
        <web-resource-collection>
                        <web-resource-name>Member Area</web-resource-name>
                        <url-pattern>/members/*</url-pattern>

                        <http-method>DELETE</http-method>
                        <http-method>POST</http-method>
                        <http-method>GET</http-method>
                        <http-method>PUT</http-method>

        </web-resource-collection>
        <auth-constraint>
                        <role-name>*</role-name>
        </auth-constraint>
</security-constraint>

<security-constraint>
        <web-resource-collection>
                        <web-resource-name>Schedules</web-resource-name>
                        <url-pattern>/schedule/*</url-pattern>
                        <http-method>DELETE</http-method>

                        <http-method>POST</http-method>
                        <http-method>GET</http-method>
                        <http-method>PUT</http-method>
        </web-resource-collection>

        <auth-constraint>
                        <role-name>employee</role-name>
                        <role-name>owner</role-name>
        </auth-constraint>
</security-constraint>

<security-constraint>
        <web-resource-collection>
                        <web-resource-name>Financial Info</web-resource-name>
                        <url-pattern>/financials/*</url-pattern>
                        <http-method>DELETE</http-method>

                        <http-method>POST</http-method>
                        <http-method>GET</http-method>
                        <http-method>PUT</http-method>
        </web-resource-collection>

        <auth-constraint>
                        <role-name>owner</role-name>
        </auth-constraint>
</security-constraint>

Finally, declare the roles:

<security-role>
        <role-name>employee</role-name>
</security-role>
<security-role>
        <role-name>owner</role-name>

</security-role>

For more information on security-constraint, see chapters 12 and 13 in the Java Servlet Specification.

2.3 Access-Control Configurations in EJB Modules

You configure EJB modules with access-control parameters in the ejb-jar.xml file.

2.3.1 Configurations for Authentication

Authentication of EJB components is relevant only if you plan on accessing those components through rich clients. If the entry point for access requests is through HTTP, then you need to configure the authentication for the Web module only because the user identity established by the Web container automatically propagates to the EJB container.

When accessing EJB components through rich clients, such as application clients, Application Server 7 receives the user name-password credential through IIOP and uses the credential to invoke the realm. For an implementation of IIOP over SSL, Application Server 7 obtains the client certificate through the usual SSL handshake. The security-identity element indicates the transaction with a flag called use-caller-identity, as follows:

<security-identity>
        <use-caller-identity/>
</security-identity>

Optionally, you can specify run-as with a role name, in which case Application Server 7 ignores the client's identity and the code runs with the privileges of the specified role.

2.3.2 Configurations for Authorization

Recall that for EJB components, you can specify authorization constraints by method or by component. For details, see the Enterprise JavaBeans Specification and the ejb-jar document type definition (DTD).

You declare authorization constraints from within the method-permission element by specifying the enterprise bean (that is, a value for the ejb-name element) and the method. If you apply the wildcard string * to the method, then the constraint is imposed on the entire component. Optionally, you can also specify method-param elements to distinguish between overloaded methods. Finally, you declare the name of the roles to which to grant access.

Following is the corresponding section in the ejb-jar.xml file in the same sample application.

<method-permission>
        <role-name>owner</role-name>
        <method>
                        <ejb-name>statistics</ejb-name>

                        <method-name>getAverageRevenue</method-name>
        </method>
</method-permission>
<method-permission>
        <role-name>owner</role-name>

        <role-name>employee</role-name>
        <method>
                        <ejb-name>members</ejb-name>
                        <method-name>*</method-name>

        </method>
</method-permission>

Declare the roles afterwards:

<security-role>
        <role-name>employee</role-name>

</security-role>
<security-role>
        <role-name>owner</role-name>
</security-role>

For details on authenticating and authorizing EJB components, see chapter 21 and appendix B in the Enterprise JavaBeans Specification.

2.4 Configuring Role Mappings

Remember: Access control on the J2EE platform is based on application roles. Those roles reside within the application; however, it's actual users who authenticate to Application Server 7. To determine whether to grant access of a protected area to a user, Application Server 7 must be privy to how the roles correspond to the users. That's where role mappings come into play.

Role mapping is determined by the security-role-mapping elements in the application descriptor. Here is a simple example:

<security-role-mapping>
        <role-name>manager</role-name>
        <principal-name>javajoe</principal-name>
        <group-name>mgrs</group-name>

</security-role-mapping>

This mapping declares that the application role manager consists of the user javajoe and all the users who belong to the mgrs group. In other words, to access a protected Web area or EJB component that requires the role manager, the user who logs in must either be javajoe or be a member of the mgrs group.

Group membership is determined by the active realm, not by Application Server 7. The realm implementation defines the group names to which authenticated users belong, if any, as discussed in the section, Authentication Realms.

You can map an application role to any number (zero or more) of principal-name and group-name elements. Also, an application can have any number of security-role-mapping elements.

Be sure to place the security-role-mapping elements in the correct locations, as follows:

  • For all applications packaged as .ear files, place those elements in the sun-application.xml descriptor.

  • For standalone applications or modules that have no sun-application.xml descriptor files, place the elements in the module-level descriptor file (sun-web.xml or sun-ejb-jar.xml).

Note - If an application (.ear file) contains security-role-mapping elements within module-level descriptor files, Application Server 7 ignores those elements.

For logins to be successful, the users and groups referenced in the security-role-mapping elements must exist in the user database of the realm. If you are using the built-in file realm (FileRealm), you can add or revise user data in keyfile, as necessary, from the Application Server 7 console. For other realms, use the corresponding product's interface for the task. For example, if you are using the LDAP realm (LDAPRealm), create or modify your user database with the tools provided by the LDAP server.

You've now configured access control for your application. In case of problems, see the section on troubleshooting tips.

3. Other Security-Related Capabilities

This section describes other security-related capabilities offered by Application Server 7:

3.1 Audit Logs

The security-service element in the server.xml file contains a flag called audit-enabled. If you set this flag to true, Application Server 7 logs an audit trail of all authentication and authorization decisions.

Authentication log entries include the following information:

  • The names of the users who have attempted to authenticate
  • The realm that processed the access requests
  • The areas (Web URI or EJB component) that pertain to the requests
  • Success or failure of the requests

To alert administrators of potential security attacks, regardless of the setting of the audit-enabled flag, Application Server 7 logs all denied authentication events.

Authorization log entries include the following information:

  • The names of the authenticated users, if any
  • The areas (Web URI or EJB component) that pertain to the requests
  • Success or failure of the requests

For details on audit logs, see the section on security-service in the Application Server 7 Administrator's Configuration File Reference.

3.2 Single Sign-On (SSO)

A convenient and time-saving capability, Single Sign-On (SSO) is intended for multiple, integrated, and related applications, to which users need log in one time only. For HTTP connections, Application Server 7 supports SSO across Web applications in the same instance and the same virtual server. That is, once Application Server 7 has authenticated and granted access to a user to any one application, that user's identity automatically propagates to any other applications on that server instance.

In certain circumstances, however, identity propagation in SSO can lead to confusing results. A couple of example scenarios--

  • If you are authenticated to application A and later on attempt to access application B, to which you have no access privilege, Application Server 7 denies your request for application B. Because your identity has already been established, application B does not prompt you for reauthentication.

    To access application B, assuming that application A provides a logout capability, you must first log out of application A and then access application B. With your identity cleared by the logout, application B prompts for reauthentication.

    Hence, SSO is recommended for applications that collaborate with each other, to which users can log in with consistent identities. If users must switch identities between applications, do not use SSO.

  • Applications A and B both use HTTP BASIC authorization and the application code attempts to retrieve the Authorization header from the HTTP request. After authenticating to and working with application A, you access application B. With SSO in effect, Application Server 7 propagates your user identity to application B and enables you to log in.

    Since application B need not independently authenticate users, it does not generate a 401 response to the browser to send the Authorization header to application B itself. As a result, even though you've been authenticated, if application B attempts to retrieve that header from the request, it won't find the header.

To avoid such confusions, disable SSO. Do so by setting the sso-enabled flag in server.xml to false.

For details on SSO, see the section, User Authentication for Single Sign-on, in the Application Server 7 Developer's Guide to Web Applications.

3.3 HTTP Sessions

When Application Server 7 authenticates a user for an application that uses sessions, that user's identity becomes part of the session, with the following implications:

  • As long as the session is active and valid, all requests associated with the session are automatically associated with the authenticated user.

  • All subsequent requests within the lifetime of the session will not trigger another authentication process. That is, for so long as the user is in the session, Application Server 7 does not invoke the realm for reauthentication.

  • To enable the user to log out, the application must invalidate the session by invoking the HttpSession.invalidate() method.

  • Sessions can expire according to the configured timeout. Once a session has expired, the next request from the user will trigger reauthentication, if necessary.

Developers who design or implement authentication schemes must be aware of HTTP sessions, also called servlet sessions. For details, see chapter 7 in the Java Servlet Specifications.

3.4 HTTP BASIC Authentication

HTTP BASIC, a simple authentication method, is defined at the HTTP protocol level (unlike FORM authentication, for example).

HTTP BASIC authentication functions this way: If a client, typically a browser, has verified that it holds the appropriate credentials for the access request it is generating, the client sends an Authorization header with the authentication-related information. Some browser implementations differ slightly in their interpretation of when they are to send previously established credentials. To determine the exact browser behavior, snoop the HTTP request headers being sent to Application Server 7.

Remember: Application Server 7 does not control the point at which the browser sends the header. That also means that the notion of logout does not apply for HTTP BASIC authentication. Once a browser obtains a valid combination of user name and password for a protected area, that is, the server does not respond with a 401 request, the browser continues to send credentials in the Authorization header in all future requests until the credentials are no longer available. The browser implementation determines how to remove the credential information. With most of today's browsers, the only way you can remove the information is to restart the browser.

Confusion often results when an application uses both BASIC authentication and HTTP sessions, as described in the previous section. After the user has been authenticated, the login credential becomes part of the session and subsequent requests will not trigger another authentication process. However, the browser is not aware of this rule and continues to send the Authorization header for all subsequent access requests. If the server invalidates or terminates the session, the next request requires reauthentication. However, this reauthentication occurs automatically because the credentials are already in the request. You can easily trace and observe this behavior in the audit logs.

For security, if your application requires a guarantee of logout (or expiration) of authenticated credentials, do not use BASIC as the authentication scheme. Use FORM instead.

For details on HTTP BASIC authentication, see this paper from The Internet Engineering Task Force.

3.5 Programmatic Login

Application Server 7 provides an interface for application code to programmatically trigger an authentication event. If authentication succeeds, the security context for the request becomes associated with the authenticated user--just as if the context had been established through container-managed authentication.

With programmatic login, keep in mind that authentication can occur only after the application has run and invoked the login method. For example, if your application restricts access to /*, it cannot use programmatic login because the code never gets a chance to run. To implement programmatic login, you must structure the protected areas such that an unprotected entry point is available for the login process to occur. Because filters also run after authentication is enforced, you cannot bypass this restriction by invoking programmatic login from a filter.

Following is an example of using programmatic login from a servlet.

import com.sun.appserv.security.ProgrammaticLogin;
    [...]
ProgrammaticLogin pm = new ProgrammaticLogin();

Boolean success = pm.login("user", "secret", request, response);
if (success.booleanValue()) {
        // login ok; handle success case
} else {
        // login failed; handle failure
}

A corresponding login() method is available for use from EJB components. Though identical to the servlet method, login() does not provide the HTTP request and response objects.

Note - Be sure to grant the related applications permission to use programmatic login; that permission is not granted by default. See "Programmatic Login" in the Application Server 7 Developer's Guide.

The application code determines how and from where to obtain the user credential, such as a combination of user name and password. That credential must be strings that can be correctly interpreted by the realm in the server instance.

As an example, you can build a custom realm to interpret the values as desired. Some deployments use an authentication server in front of Application Server 7 to perform authentication. In that case, the HTTP request can simply contain an opaque cookie that links the request to a user. You can pass the cookie as the password value to a custom realm through programmatic login. Through external APIs, the corresponding custom realm can associate the cookie with an authenticated user.

The ProgrammaticLogin class is defined in a Java archive (JAR) file called lib/appserv-rt.jar. To avoid a compile-time dependency on the file, invoke programmatic login through reflection.

For details, see "Programmatic Login" in the Application Server 7 Developer's Guide.

3.6 Java SecurityManager

Java SecurityManager, a component of the Java 2 Platform, Standard Edition (J2SE), is not part of Application Server 7 but is active there. It enforces the security policy and prevents Java code from invoking restricted operations--a task that's entirely unrelated to access control in J2EE applications.

Java SecurityManager imposes no restrictions on Application Server 7 operations. Deployed applications, however, run under limited permissions only. You can review or revise the permissions that are assigned to deployed applications in the server.policy configuration file.

Because Java SecurityManager evaluates the policy for every invocation that's potentially restricted, degradation in performance may result. To determine whether to disable Java SecurityManager, read the following documents that describe Java Security Manager and its functions in Application Server 7 in detail:

3.7 SSL and TLS Configurations

You configure SSL and TLS in the server.xml file and store the keys and certificates in opaque *.db files in the config directory. Application Server 7's administration console provides the interfaces to configure SSL. For details, see the Application Server 7 documentation.

One aspect of SSL configurations that can be confusing is the client-auth-enabled flag, specified under the ssl element in the server.xml file. If you set this flag to true, Application Server 7 requires the client, usually the browser, to present a valid certificate when initiating a connection--regardless of the access-control configurations in the application (or lack thereof). Failing that, Application Server 7 rejects the connection.

Configure as follows:

  • To trigger authentication of clients according to the configuration of the application (that is, CLIENT-CERT auth-method in the web.xml file), set client-auth-enabled to false.

  • To trigger authentication of clients through certificates at all times, regardless of whether or not you use CLIENT-CERT auth-method, set client-auth-enabled to true.

3.7.1 Self-Signed Certificates

You can create a self-signed certificate for development, testing, or deployment on intranets with the Network Security Services (NSS) command-line interface (CLI) tools. Though the NSS tools are part of Application Server 7, you must download them separately, either from the Sun Download Center (click the link for Update 2 Add-ons) or from mozilla.org. To ensure compatibility between the versions for the tool and for the Application Server 7 library, download the tools from Sun. Further, Sun supports only the NSS tools from the Application Server 7 add-on pack.

For documentation on the NSS tools, go to mozilla.org. For details on using certificates, see the certutil documentation.

Following is a tutorial on how to set up Application Server 7 with a self-signed certificate. The steps take place in the config directory of the server instance that is being configured.

  1. Go to the config directory of the server instance you are configuring. Type:

    % cd appserver_install_path/domains/domain/server1/config/

  2. Initialize the certification-key database.

    This step is performed once only during installation. Skip this step if you have already initialized the database. Do either of the following:

    • From the command line, type:

              % certutil -d . -N
      
      Afterward, you are prompted to enter a password twice. Type a password for the database.

    • From the administration console, choose Manage Database from the Security menu and then type a password for the database. Click OK.

  3. Create a certificate-key pair to be used as your own Certificate Authority (CA).

    See the documentation on certutil for a description of the options and set their values as desired. For example, you may likely change the CA Distinguished Name (DN) with the -s option and the expiration time with the -v option. Here is an example of the command line (all in one line):

    % certutil -S -d . -n SelfCA -s "CN=Self CA,OU=xyz.com,C=US" -x -t "CTu,CTu,CTu" -m 101 -v 99 -5

    1. Follow the screen prompts to generate a key.

      Afterwards, certutil displays this prompt:

      Generating key. This may take a few moments -
      0 - SSL Client
      1 - SSL Server
      2 - S/MIME
      3 - Object Signing
      4 - Reserved for Future Use
      5 - SSL CA
      6 - S/MIME CA
      7 - Object Signing CA
      Other to finish
      
    2. Type 5. When the prompt is redisplayed, type 9 to finish.

      A question is then displayed: "Is this a critical extension [y/n]?"

    3. Type y in answer.

  4. Create a server-key pair and issue the server a certificate signed by your CA (created in step 3).

    Again, follow the certutil documentation and adjust the options to suit your requirements. Be sure to change the server DN with the -s option to reflect the name of your Web server host. Here is an example of the command line (all in one line):

    % certutil -S -d . -n MyServerCert -s "CN=www,OU=xyz.com,C=US" -c SelfCA -t "u,u,u" -m 102 -v 99 -5

    1. Follow the screen prompts to generate a key.

      Afterwards, certutil displays this prompt:

      Generating key. This may take a few moments -
      0 - SSL Client
      1 - SSL Server
      2 - S/MIME
      3 - Object Signing
      4 - Reserved for Future Use
      5 - SSL CA
      6 - S/MIME CA
      7 - Object Signing CA
      Other to finish
      
    2. Type 1. When the prompt is redisplayed, type 2. When the prompt is again redisplayed, type 3. Afterwards, type 9 to finish.

      A question is then displayed: "Is this a critical extension [y/n]?"

    3. Type y in answer.

  5. Ensure that your CA and the self-signed server certificate are in the database. Do one of the following:

    • From the command line, type:

      % certutil -L -d .
      
      Verify that the display shows entries for both SelfCA and MyServerCert or the corresponding nicknames you assigned.

    • From the administration console, choose Certificate Management from the Security menu, then choose Manage.

      Verify that the display lists entries for both SelfCA and MyServerCert in addition to the built-in commercial CA certificates for your server. You can click the links to see the details of each of the certificates.

  6. Configure SSL and TLS on your server instance from the administration console. Do the following:

    1. Click the HTTP Server tab and then the HTTP Listeners tab.

    2. Select the appropriate listener as the default, for example, http-listener-1.

    3. Select the SSL/TLS Enabled checkbox and choose a nickname (MyServerCert in the preceding example) for your server certificate.

    4. Select the ciphers as appropriate and click Save to apply the changes.

    5. Restart Application Server 7.

Application Server 7 now uses your self-signed certificate as its server certificate. To verify, connect to the server from a browser that supports SSL. Because your new CA is not known to the browser, the latter will prompt you to accept the CA.

3.7.2 References

For details on SSL and TLS configurations, see the following documents:

4. Troubleshooting Tips

Debugging access control configurations can initially seem complex. Because the primary purpose of access control is to prevent unauthorized access to application resources, precisely correct configurations are mandatory. Otherwise, Application Server 7 rejects requests and troubleshooting may be problematic.

Basically, the J2EE access-control model is a simple design. Once you've familiarized yourself with its nuances, the audit logs in Application Server 7 can provide many clues that make it easy to spot problems.

Here are a few guidelines and tips:

  • Review the procedures under Implementation of Access Control in J2EE Applications and verify that you have performed the steps correctly.

  • Be sure to differentiate between authentication failures and authorization failures. Even if authentication succeeds, authorization may fail. A common misconception is that both processes are the same. The output from the audit log is particularly helpful in identifying which one is failing.

  • Increase the verbosity of the Application Server 7 log by setting the log level to FINEST. However, verbose logging severely impacts performance--turn it on only when you're debugging.

    You can set the log level individually by server component (for example, security-service) or globally. Application Server 7 logs details of its authentication and authorization decisions as well as the factors, such as roles and mapping information, responsible for the decisions.

  • While running simple applications, for example, the bundled samples, that work correctly, observe the logs. Watch for the log trace of events and look for any significant differences between the logs of a successful run versus that of a failed run. You can often pinpoint problem areas in your application this way.

  • Turn on audit logging and screen all the entries in server.log. You can then detect the point at which the failure occurs.

  • If you restart Application Server 7 when audit logging is active and the log level is set at FINEST, the log displays a table, titled "Role and ACL Summary," for each of the deployed applications. In the table are all the restricted components in the application and the associated role requirements. Compare the table with the intended configuration of your application. Differences between the two likely mean a misconfiguration in the application's descriptor files.

  • When contacting Support, always provide the following information:

    • The contents of the files in the config directory of your server instance.

    • The contents of the *.xml application descriptor files in your application, for example, web.xml and sun-web.xml

    • The relevant source code from your application if the problem relates to a programmatic API

    • A server.log file that includes the server startup and request processing logs for the failure case, generated with the log level set at FINEST and audit-enabled set to true

  • In case of an AccessControlException error, see the section Java SecurityManager for information on its policy. For a test, temporarily turn off Java SecurityManager. If the problem is resolved that way, the result points to a misconfiguration in the permissions.

5. Custom Authorizations

Application Server 7 processes decisions on authorization according to the application and server configurations described earlier in this guide and the authorization logic defined in the J2EE specifications. Application Server 7 does not support plug-in custom authorization modules as a substitute for the built-in logic.

In most cases, custom authorization modules are not necessary. You can achieve the same results by using the configurations supported by Application Server 7, such as custom realms. A custom realm can programmatically assign group membership to authenticated users through any logic, including dynamic logic.

Consider this example. Since J2EE access control does not support the encoding of time-based access rights, you plan to plug in a custom authorization module that grants or denies access to users according to the time of the day. Instead of doing so, adopt this alternative design instead:

  • Define the roles that correspond to the time periods that have different access requirements, for example, day-operator and night-operator. Define access rules in the Web or EJB modules to restrict operations on the basis of those roles.

  • Map the roles to the appropriate groups, for example, day-operator-group and night-operator-group.

  • Build a custom realm that assigns users who log in to the appropriate groups according to the time of the day.

This is just one potential solution. You can also accomplish similar functionality through the mechanism of application-managed security.

J2EE 1.4 contains an implementation of the Java Authorization Contract for Containers (JACC) through Java Specification Request (JSR) 115. JACC provides custom pluggable authorization modules. The next major release of Application Server will support this functionality.

6. Native Access Control Lists

Application Server 7 incorporates the core HTTP engine from Sun Java System Web Server (formerly Sun ONE Web Server and hereinafter called Web Server). That engine supports access control through a flexible framework for access control lists (ACLs) that is enforced outside the Java environment. That is an entirely separate framework from the one for J2EE access control and is outside the scope of this guide. For details on core ACLs, see "Administering HTTP Server Access Control" in the Application Server 7 Administrator's Guide to Security.

In general, using the ACL mechanism to restrict access to J2EE applications is not recommended because of the following:

  • Configuring access control with the J2EE mechanisms, as described in this guide, makes your applications more portable and simplifies maintenance because the configuration details are integrated within the application's deployment descriptors.
  • The Java Web container in Application Server 7 is not integrated into the ACL mechanism. Hence, if you authenticate and authorize requests through core ACLs, you cannot programmatically access the user or authentication data. For example, because the Web container is not aware of the authenticated users, request.getUserPrincipal() always returns null.

Nonetheless, in some cases, making use of the core ACL capabilities is a wiser choice. A few examples--

  • If you are migrating from Web Server and are familiar with the ACL mechanism, feel free to use ACL. As long as your J2EE applications do not require programmatic access to the authentication data, ACL works well.

  • If you are hosting sites with a mixture of J2EE and non-J2EE content, the J2EE access control scheme may not be satisfactory because it applies only to the content in J2EE applications. In this case, it may be more convenient to centralize all the access-control schemes for your site with core ACLs.

  • If your application has unique dependencies, such as custom Netscape Server Application Programming Interface (NSAPI) plugins that are related to access control and that you do not plan to port to the Java platform, ACL may be your answer.

As a rule, adopting a mixture of two access-control frameworks is problem prone. Carefully gauge your requirements, and then pick one or the other and implement it uniformly across your application.

7. About the Authors

Jyri Virkki, a specialist in server development and network security for the past decade, has been with Sun Microsystems for nearly seven years. He was the security architect and lead security developer for Sun Java System Application Server 7.

Marina Sum is a staff writer for Sun Developer Network. She has been writing for Sun for 14 years, mostly in the technical arena.

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.