bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Developing Security Providers for WebLogic Server

Role Mapping Providers

Role mapping is the process whereby principals (users or groups) are dynamically mapped to security roles at runtime. In WebLogic Server, a Role Mapping provider determines what security roles apply to the principals stored a subject when the subject is attempting to perform an operation on a WebLogic resource. Because this operation usually involves gaining access to the WebLogic resource, Role Mapping providers are typically used with Authorization providers.

The following sections describe Role Mapping provider concepts and functionality, and provide step-by-step instructions for developing a custom Role Mapping provider:

- Role Mapping Concepts

- The Role Mapping Process

- Do You Need to Develop a Custom Role Mapping Provider?

- How to Develop a Custom Role Mapping Provider

Role Mapping Concepts

Before you develop a Role Mapping provider, you need to understand the following concepts:

- Security Roles

- Dynamic Security Role Computation

- Security Providers and WebLogic Resources

Security Roles

A security role is a named collection of users or groups that have similar permissions to access WebLogic resources. Like groups, security roles allow you to control access to WebLogic resources for several users at once. However, security roles are scoped to specific resources in a WebLogic Server domain (unlike groups, which are scoped to an entire WebLogic Server domain), and can be defined dynamically (as described in Dynamic Security Role Computation).

Notes: For more information about security roles, see "Security Roles" in Securing WebLogic Resources. For more information about WebLogic resources, see Security Providers and WebLogic Resources, and "WebLogic Resources" in Securing WebLogic Resources.

The SecurityRole interface in the weblogic.security.service package is used to represent the abstract notion of a security role. (For more information, see the WebLogic Server 7.0 API Reference Javadoc for the SecurityRole interface.)

Mapping a principal to a security role grants the defined access permissions to that principal, as long as the principal is "in" the security role. For example, an application may define a security role called AppAdmin, which provides write access to a small subset of that application's resources. Any principal in the AppAdmin security role would then have write access to those resources. For more information, see Dynamic Security Role Computation and "Security Roles" in Securing WebLogic Resources.

Many principals can be mapped to a single security role. For more information about principals, see Users and Groups, Principals and Subjects.

Security roles are specified in Java 2 Enterprise Edition (J2EE) deployment descriptor files and/or in the WebLogic Server Administration Console. For more information, see Managing Role Mapping Providers and Deployment Descriptors.

Dynamic Security Role Computation

Security roles can be declarative (that is, Java 2 Enterprise Edition roles) or dynamically computed based on the context of the request.

Dynamic role computation is the term for this late binding of principals (that is, users or groups) to security roles at runtime. The late binding occurs just prior to an authorization decision for a protected WebLogic resource, regardless of whether the principal-to-security role association is statically defined or dynamically computed. Because of its placement in the invocation sequence, the result of any principal-to-security role computations can be taken as an authentication identity, as part of the authorization decision made for the request.

This dynamic computation of security roles provides a very important benefit: users or groups can be granted a security role based on business rules. For example, a user may be allowed to be in a Manager security role only while the actual manager is away on an extended business trip. Dynamically computing this security role means that you do not need to change or redeploy your application to allow for such a temporarily arrangement. Further, you would not need to remember to revoke the special privileges when the actual manager returns, as you would if you temporarily added the user to a Managers group.

Note: You typically grant users or groups security roles using the role conditions available in the WebLogic Server Administration Console. (In this release of WebLogic Server, you cannot write custom role conditions.) For more information, see "Security Roles" in Securing WebLogic Resources.

The computed security role is able to access a number of pieces of information that make up the context of the request, including the identity of the target (if available) and the parameter values of the request. The context information is typically used as values of parameters in an expression that is evaluated by the WebLogic Security Framework. This functionality is also responsible for computing security roles that were statically defined through a deployment descriptor or through the WebLogic Server Administration Console.

Notes: The computation of security roles for an authenticated user enhances the Role-Based Access Control (RBAC) security defined by the Java 2 Enterprise Edition (J2EE) specification.

You create dynamic security role computations by defining role statements in the WebLogic Server Administration Console. For more information, see "Security Roles" in Securing WebLogic Resources.

The Role Mapping Process

The WebLogic Security Framework calls each Role Mapping provider that is configured for a security realm as part of an authorization decision. For related information, see The Authorization Process.

The result of the dynamic role computation (performed by the Role Mapping providers) is a set of security roles that apply to the principals stored in a subject at a given moment. These security roles can then be used to make authorization decisions for protected WebLogic resources, as well as for resource container and application code. For example, an Enterprise JavaBean (EJB) could use the Java 2 Enterprise Edition (J2EE) isCallerInRole method to retrieve fields from a record in a database, without having knowledge of the business policies that determine whether access is allowed.

Figure 8-1 shows how the Role Mapping providers interact with the WebLogic Security Framework to create dynamic role computations, and an explanation follows.

Figure 8-1 Role Mapping Providers and the Role Mapping Process

Generally, role mapping is performed in the following manner:

1. A user or system process requests a WebLogic resource on which it will attempt to perform a given operation.

2. The resource container that handles the type of WebLogic resource being requested receives the request (for example, the EJB container receives the request for an EJB resource).

   Note: The resource container could be the container that handles any one of the WebLogic Resources described in Security Providers and WebLogic Resources.

3. The resource container constructs a ContextHandler object that may be used by Role Mapping providers to obtain information associated with the context of the request.

   Note: For more information about ContextHandlers, see ContextHandlers and WebLogic Resources.

   The resource container calls the WebLogic Security Framework, passing in the subject (which already contains user and group principals), an identifier for the WebLogic resource, and optionally, the ContextHandler object (to provide additional input).

   Note: For more information about subjects, see Users and Groups, Principals and Subjects. For more information about resource identifiers, see WebLogic Resource Identifiers.

4. The WebLogic Security Framework calls each configured Role Mapping provider to obtain a list of the security roles that apply. This works as follows:

   1. The Role Mapping providers use the ContextHandler to request various pieces of information about the request. They construct a set of Callback objects that represent the type of information being requested. This set of Callback objects is then passed as an array to the ContextHandler using the handle method.

      The Role Mapping providers may call the ContextHandler more than once in order to obtain the necessary context information. (The number of times a Role Mapping provider calls the ContextHandler is dependent upon its implementation.)

   2. Using the context information and their associated security provider databases containing security policies, the subject, and the WebLogic resource, the Role Mapping providers determine whether the requestor (represented by the user and group principals in the subject) is entitled to a certain security role.

      The security policies are represented as a set of expressions or rules that are evaluated to determine if a given security role is to be granted. These rules may require the Role Mapping provider to substitute the value of context information obtained as parameters into the expression. In addition, the rules may also require the identity of a user or group principal as the value of an expression parameter.

      Note: The rules for security policies are set up in the WebLogic Server Administration Console and in Java 2 Enterprise Edition (J2EE) deployment descriptors. For more information, see "Security Policies" in Securing WebLogic Resources.

   3. If a security policy specifies that the requestor is entitled to a particular security role, the security role is added to the list of security roles that are applicable to the subject.

   4. This process continues until all security policies that apply to the WebLogic resource or the resource container have been evaluated.

5. The list of security roles is returned to the WebLogic Security Framework, where it can be used as part of other operations, such as access decisions.

Do You Need to Develop a Custom Role Mapping Provider?

The default (that is, active) security realm for WebLogic Server includes a WebLogic Role Mapping provider. The WebLogic Role Mapping provider computes dynamic security roles for a specific user (subject) with respect to a specific protected WebLogic resource for each of the default users and WebLogic resources. The WebLogic Role Mapping provider supports the deployment and undeployment of security roles within the system. The WebLogic Role Mapping provider uses the same security policy engine as the WebLogic Authorization provider. If you want to use a role mapping mechanism that already exists within your organization, you could create a custom Role Mapping provider to tie into that system.

How to Develop a Custom Role Mapping Provider

If the WebLogic Role Mapping provider does not meet your needs, you can develop a custom Role Mapping provider by following these steps:

1. Create Runtime Classes Using the Appropriate SSPIs

2. Generate an MBean Type Using the WebLogic MBeanMaker

3. Configure the Custom Role Mapping Provider Using the Administration Console

4. Provide a Mechanism for Security Role Management

Create Runtime Classes Using the Appropriate SSPIs

Before you start creating runtime classes, you should first:

- Understand the Purpose of the "Provider" SSPIs

- Determine Which "Provider" Interface You Will Implement

- Understand the SSPI Hierarchy and Determine Whether You Will Create One or Two Runtime Classes

When you understand this information and have made your design decisions, create the runtime classes for your custom Role Mapping provider by following these steps:

- Implement the RoleProvider SSPI or Implement the DeployableRoleProvider SSPI

- Implement the RoleMapper SSPI

- Implement the SecurityRole Interface

Note: At least one Role Mapping provider in a security realm must implement the DeployableRoleProvider SSPI, or else it will be impossible to deploy Web applications and EJBs.

For an example of how to create a runtime class for a custom Role Mapping provider, see Example: Creating the Runtime Class for the Sample Role Mapping Provider.

Implement the RoleProvider SSPI

To implement the RoleProvider SSPI, provide implementations for the methods described in Understand the Purpose of the "Provider" SSPIs and the following method:

  getRoleMapper

  public RoleMapper getRoleMapper()

  The getRoleMapper method obtains the implementation of the RoleMapper SSPI. For a single runtime class called MyRoleProviderImpl.java, the implementation of the getRoleMapper method would be:

  return this;

  If there are two runtime classes, then the implementation of the getRoleMapper method could be:

  return new MyRoleMapperImpl;

  This is because the runtime class that implements the RoleProvider SSPI is used as a factory to obtain classes that implement the RoleMapper SSPI.

For more information about the RoleProvider SSPI and the getRoleMapper method, see the WebLogic Server 7.0 API Reference Javadoc.

Implement the DeployableRoleProvider SSPI

To implement the DeployableRoleProvider SSPI, provide implementations for the methods described in Understand the Purpose of the "Provider" SSPIs, Implement the RoleProvider SSPI, and the following methods:

  deployRole

  public void deployRole(Resource resource, java.lang.String roleName, java.lang.String[] userAndGroupNames) throws RoleCreationException

  The deployRole method creates a security role on behalf of a deployed Web application or EJB, based on the WebLogic resource to which the security role should apply, the name of the security role within the application, and the user and group names that are in the security role.

  undeployRole

  public void undeployRole(Resource resource, java.lang.String roleName) throws RoleRemovalException

  The undeployRole method deletes a security role on behalf of an undeployed Web application or EJB, based on the WebLogic resource to which the security role applied and the name of the security role within the application.

For more information about the DeployableRoleProvider SSPI and the deployRole and undeployRole methods, see the WebLogic Server 7.0 API Reference Javadoc.

Implement the RoleMapper SSPI

To implement the RoleMapper SSPI, provide implementations for the following methods:

  getRoles

  public Map getRoles(Subject subject, Resource resource, ContextHandler handler)

  The getRoles method returns the security roles associated with a given subject for a specified WebLogic resource, possibly using the optional information specified in the ContextHandler. For more information about ContextHandlers, see ContextHandlers and WebLogic Resources.

For more information about the RoleMapper SSPI and the getRoles methods, see the WebLogic Server 7.0 API Reference Javadoc.

Developing Custom Role Mapping Providers That Are Compatible With the Realm Adapter Authentication Provider

An Authentication provider is the security provider responsible for populating a subject with users and groups, which are then extracted from the subject by other types of security providers, including Role Mapping providers. If the Authentication provider configured in your security realm is a Realm Adapter Authentication provider, the user and group information will be stored in the subject in a way that is slightly different from other Authentication providers. Therefore, this user and group information must also be extracted in a slightly different way.

Listing 8-1 provides code that can be used by custom Role Mapping providers to check whether a subject matches a user or group name when a Realm Adapter Authentication provider was used to populate the subject. This code belongs in the getRoles method.

Listing 8-1 Sample Code to Check if a Subject Matches a User or Group Name

>     /**
>      * Determines if the Subject matches a user/group name.
>      *
>      * @param principalWant A String containing the name of a principal in this role
>      * (that is, the role definition).
>      *
>      * @param subject A Subject that contains the Principals that identify the user
>      * who is trying to access the resource as well as the user's groups.
>      *
>      * @return A boolean. true if the current subject matches the name of the
>      * principal in the role, false otherwise.
>      */
>     private boolean subjectMatches(String principalWant, Subject subject)
>     {
>        // first, see if it's a group name match
>        if (SubjectUtils.isUserInGroup(subject, principalWant)) {
>           return true;
>        }
>        // second, see if it's a user name match
>        if (principalWant.equals(SubjectUtils.getUsername(subject))) {
>           return true;
>        }
>        // didn't match
>        return false;
>     }

Implement the SecurityRole Interface

The methods on the SecurityRole interface allow you to obtain basic information about a security role, or to compare it to another security role. These methods are designed for the convenience of security providers.

Note: SecurityRole implementations are returned as a Map by the getRoles() method (see Implement the RoleMapper SSPI).

To implement the SecurityRole interface, provide implementations for the following methods:

  equals

  public boolean equals( java.lang.Object another )

  The equals method returns TRUE if the security role passed in matches the security role represented by the implementation of this interface, and FALSE otherwise.

  toString

  public String toString()

  The toString method returns this security role, represented as a String.

  hashCode

  public int hashCode()

  The hashCode method returns a hashcode for this security role, represented as an integer.

  getName

  public String getName()

  The getName method returns the name of this security role, represented as a String.

  getDescription

  public String getDescription()

  The getDescription method returns a description of this security role, represented as a String. The description should describe the purpose of this security role.

Example: Creating the Runtime Class for the Sample Role Mapping Provider

Listing 8-2 shows the SampleRoleMapperProviderImpl.java class, which is the runtime class for the sample Role Mapping provider. This runtime class includes implementations for:

- The three methods inherited from the SecurityProvider interface: initialize, getDescription and shutdown (as described in Understand the Purpose of the "Provider" SSPIs.)

- The method inherited from the RoleProvider SSPI: the getRoleMapper method (as described in Implement the RoleProvider SSPI).

- The two methods in the DeployableRoleProvider SSPI: the deployRole and undeployRole methods (as described in Implement the DeployableRoleProvider SSPI).

- The method in the RoleMapper SSPI: the getRoles method (as described in Implement the RoleMapper SSPI).

Note: The bold face code in Listing 8-2 highlights the class declaration and the method signatures.

Listing 8-2 SampleRoleMapperProviderImpl.java

>     package examples.security.providers.roles;

>     import java.security.Principal;
>     import java.util.Collections;
>     import java.util.Enumeration;
>     import java.util.HashMap;
>     import java.util.Iterator;
>     import java.util.Map;
>     import java.util.Properties;
>     import java.util.Set;
>     import javax.security.auth.Subject;
>     import weblogic.management.security.ProviderMBean;
>     import weblogic.security.WLSPrincipals;
>     import weblogic.security.service.ContextHandler;
>     import weblogic.security.spi.DeployableRoleProvider;
>     import weblogic.security.spi.Resource;
>     import weblogic.security.spi.RoleCreationException;
>     import weblogic.security.spi.RoleMapper;
>     import weblogic.security.spi.RoleRemovalException;
>     import weblogic.security.spi.SecurityServices;

>     public final class SampleRoleMapperProviderImpl implements DeployableRoleProvider, RoleMapper
>     {
>        private String description;
>        private SampleRoleMapperDatabase database;
>        private static final Map NO_ROLES = Collections.unmodifiableMap(new
>          HashMap(1));

>        public void initialize(ProviderMBean mbean, SecurityServices services)
>        {
>           System.out.println("SampleRoleMapperProviderImpl.initialize");
>           SampleRoleMapperMBean myMBean = (SampleRoleMapperMBean)mbean;
>           description = myMBean.getDescription() + "\n" + myMBean.getVersion();
>           database = new SampleRoleMapperDatabase(myMBean);
>        }

>        public String getDescription()
>        {
>           return description;
>        }

>        public void shutdown()
>        {
>           System.out.println("SampleRoleMapperProviderImpl.shutdown");
>        }

>        public RoleMapper getRoleMapper()
>        {
>           return this;
>        }

>        public Map getRoles(Subject subject, Resource resource, ContextHandler
>        handler)
>        {
>           System.out.println("SampleRoleMapperProviderImpl.getRoles");
>           System.out.println("\tsubject\t= " + subject);
>           System.out.println("\tresource\t= " + resource);

>           Map roles = new HashMap();
>           Set principals = subject.getPrincipals();

>           for (Resource res = resource; res != null; res = res.getParentResource())
>           {
>              getRoles(res, principals, roles);
>           }

>           getRoles(null, principals, roles);

>           if (roles.isEmpty()) {
>              return NO_ROLES;
>           }

>           return roles;
>        }

>        public void deployRole(Resource resource, String roleName, String[]
>        principalNames) throws RoleCreationException
>        {
>           System.out.println("SampleRoleMapperProviderImpl.deployRole");
>           System.out.println("\tresource\t\t= " + resource);
>           System.out.println("\troleName\t\t= " + roleName);

>           for (int i = 0; principalNames != null && i < principalNames.length; i++)
>           {
>              System.out.println("\tprincipalNames[" + i + "]\t= " +
>              principalNames[i]);
>           }

>           database.setRole(resource, roleName, principalNames);
>        }

>        public void undeployRole(Resource resource, String roleName) throws
>        RoleRemovalException
>        {
>           System.out.println("SampleRoleMapperProviderImpl.undeployRole");
>           System.out.println("\tresource\t= " + resource);
>           System.out.println("\troleName\t= " + roleName);

>           database.removeRole(resource, roleName);
>        }

>        private void getRoles(Resource resource, Set principals, Map roles)
>        {
>           for (Enumeration e = database.getRoles(resource); e.hasMoreElements();)
>           {
>              String role = (String)e.nextElement();
>              if (roleMatches(resource, role, principals))
>              {
>                 roles.put(role, new SampleSecurityRoleImpl(role, "no description"));
>              }
>           }
>        }

>        private boolean roleMatches(Resource resource, String role, Set
>        principalsHave)
>        {
>           for (Enumeration e = database.getPrincipalsForRole(resource, role);
>             e.hasMoreElements();)
>           {
>              String principalWant = (String)e.nextElement();
>              if (principalMatches(principalWant, principalsHave))
>              {
>                 return true;
>              }
>           }
>           return false;
>        }

>        private boolean principalMatches(String principalWant, Set principalsHave)
>        {
>           if (WLSPrincipals.getEveryoneGroupname().equals(principalWant) ||
>             (WLSPrincipals.getUsersGroupname().equals(principalWant) &&
>             !principalsHave.isEmpty()) || (WLSPrincipals.getAnonymousUsername().
>             equals(principalWant) && principalsHave.isEmpty()) ||
>             principalsContain(principalsHave, principalWant))
>             {
>                return true;
>             }
>           return false;
>        }

>        private boolean principalsContain(Set principalsHave, String
>        principalNameWant)
>        {
>           for (Iterator i = principalsHave.iterator(); i.hasNext();)
>           {
>              Principal principal = (Principal)i.next();
>              String principalNameHave = principal.getName();
>              if (principalNameWant.equals(principalNameHave))
>              {
>                 return true;
>              }
>           }
>           return false;
>        }
>     }

Listing 8-3 shows the sample SecurityRole implementation that is used along with the SampleRoleMapperProviderImpl.java runtime class.

Listing 8-3 SampleSecurityRoleImpl.java

>     package examples.security.providers.roles;

>     import weblogic.security.service.SecurityRole;

>     public class SampleSecurityRoleImpl implements SecurityRole
>     {
>        private String _roleName;
>        private String _description;
>        private int _hashCode;

>        public SampleSecurityRoleImpl(String roleName, String description)
>        {
>           _roleName = roleName;
>           _description = description;
>           _hashCode = roleName.hashCode() + 17;
>        }

>        public boolean equals(Object secRole)
>        {
>           if (secRole == null)
>           {
>              return false;
>           }

>           if (this == secRole)
>           {
>              return true;
>           }

>           if (!(secRole instanceof SampleSecurityRoleImpl))
>           {
>              return false;
>           }

>           SampleSecurityRoleImpl anotherSecRole = (SampleSecurityRoleImpl)secRole;

>           if (!_roleName.equals(anotherSecRole.getName()))
>           {
>              return false;
>           }

>           return true;
>        }

>        public String toString () { return _roleName; }
>        public int hashCode () { return _hashCode; }
>        public String getName () { return _roleName; }
>        public String getDescription () { return _description; }
>     }

Generate an MBean Type Using the WebLogic MBeanMaker

Before you start generating an MBean type for your custom security provider, you should first:

- Understand Why You Need an MBean Type

- Determine Which SSPI MBeans to Extend and Implement

- Understand the Basic Elements of an MBean Definition File (MDF)

- Understand the SSPI MBean Hierarchy and How It Affects the Administration Console

- Understand What the WebLogic MBeanMaker Provides

When you understand this information and have made your design decisions, create the MBean type for your custom Role Mapping provider by following these steps:

1. Create an MBean Definition File (MDF)

2. Use the WebLogic MBeanMaker to Generate the MBean Type

3. Use the WebLogic MBeanMaker to Create the MBean JAR File (MJF)

4. Install the MBean Type Into the WebLogic Server Environment

Notes: Several sample security providers (available under "Code Samples: WebLogic Server" on the dev2dev Web site) illustrate how to perform these steps.

All instructions provided in this section assume that you are working in a Windows environment.

Create an MBean Definition File (MDF)

To create an MBean Definition File (MDF), follow these steps:

1. Copy the MDF for the sample Role Mapping provider to a text file.

   Note: The MDF for the sample Role Mapping provider is called SampleRoleMapper.xml.

2. Modify the content of the <MBeanType> and <MBeanAttribute> elements in your MDF so that they are appropriate for your custom Role Mapping provider.

3. Add any custom attributes and operations (that is, additional <MBeanAttribute> and <MBeanOperation> elements) to your MDF.

4. Save the file.

Note: A complete reference of MDF element syntax is available in MBean Definition File (MDF) Element Syntax.

Use the WebLogic MBeanMaker to Generate the MBean Type

Once you create your MDF, you are ready to run it through the WebLogic MBeanMaker. The WebLogic MBeanMaker is currently a command-line utility that takes as its input an MDF, and outputs some intermediate Java files, including an MBean interface, an MBean implementation, and an associated MBean information file. Together, these intermediate files form the MBean type for your custom security provider.

The instructions for generating an MBean type differ based on the design of your custom Role Mapping provider. Follow the instructions that are appropriate to your situation:

- No Custom Operations

- Custom Operations

No Custom Operations

If the MDF for your custom Role Mapping provider does not include any custom operations, follow these steps:

1. Create a new DOS shell.

2. Type the following command:

   java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker

   where the -DMDF flag indicates that the WebLogic MBeanMaker should translate the MDF into code, xmlFile is the MDF (the XML MBean Description File) and filesdir is the location where the WebLogic MBeanMaker will place the intermediate files for the MBean type.

   Whenever xmlfile is provided, a new set of output files is generated. If files already exist in the location specified by filesdir, you are informed that the existing files will be overwritten and are asked to confirm.

   Each time you use the -DcreateStubs=true flag, it overwrites any existing MBean implementation file.

   Note: The WebLogic MBeanMaker processes one MDF at a time. Therefore, you may have to repeat this process if you have multiple MDFs (in other words, multiple Role Mapping providers).

3. Proceed to Use the WebLogic MBeanMaker to Create the MBean JAR File (MJF).

Custom Operations

If the MDF for your custom Role Mapping provider does include custom operations, consider the following:

- Are you creating an MBean type for the first time? If so, follow these steps:

1. Create a new DOS shell.

2. Type the following command:

   java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker

   where the -DMDF flag indicates that the WebLogic MBeanMaker should translate the MDF into code, xmlFile is the MDF (the XML MBean Description File) and filesdir is the location where the WebLogic MBeanMaker will place the intermediate files for the MBean type.

   Whenever xmlfile is provided, a new set of output files is generated. If files already exist in the location specified by filesdir, you are informed that the existing files will be overwritten and are asked to confirm.

   Each time you use the -DcreateStubs=true flag, it overwrites any existing MBean implementation file.

   Note: The WebLogic MBeanMaker processes one MDF at a time. Therefore, you may have to repeat this process if you have multiple MDFs (in other words, multiple Role Mapping providers).

3. For any custom operations in your MDF, implement the methods using the method stubs.

4. Save the file.

5. Proceed to Use the WebLogic MBeanMaker to Create the MBean JAR File (MJF).

- Are you updating an existing MBean type? If so, follow these steps:

1. Copy your existing MBean implementation file to a temporary directory so that your current method implementations are not overwritten by the WebLogic MBeanMaker.

2. Create a new DOS shell.

3. Type the following command:

   java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker

   where the -DMDF flag indicates that the WebLogic MBeanMaker should translate the MDF into code, xmlFile is the MDF (the XML MBean Description File) and filesdir is the location where the WebLogic MBeanMaker will place the intermediate files for the MBean type.

   Whenever xmlfile is provided, a new set of output files is generated. If files already exist in the location specified by filesdir, you are informed that the existing files will be overwritten and are asked to confirm.

   Each time you use the -DcreateStubs=true flag, it overwrites any existing MBean implementation file.

   Note: The WebLogic MBeanMaker processes one MDF at a time. Therefore, you may have to repeat this process if you have multiple MDFs (in other words, multiple Role Mapping providers).

4. If you modified the MDF to include any custom operations that were not in the original MDF, implement the methods using the method stubs.

5. Save the version of the MBean implementation file that is complete (that is, has all methods implemented).

6. Copy this MBean implementation file into the directory where the WebLogic MBeanMaker placed the intermediate files for the MBean type. You specified this as filesdir in step 3. (You will be overriding the MBean implementation file generated by the WebLogic MBeanMaker as a result of step 3.)

7. Proceed to Use the WebLogic MBeanMaker to Create the MBean JAR File (MJF).

About the Generated MBean Interface File

The MBean interface file is the client-side API to the MBean that your runtime class or your MBean implementation will use to obtain configuration data. It is typically used in the initialize method as described in Understand the Purpose of the "Provider" SSPIs.

Because the WebLogic MBeanMaker generates MBean types from the MDF you created, the generated MBean interface file will have the name of the MDF, plus the text "MBean" appended to it. For example, the result of running the SampleRoleMapper MDF through the WebLogic MBeanMaker will yield an MBean interface file called SampleRoleMapperMBean.java.

Use the WebLogic MBeanMaker to Create the MBean JAR File (MJF)

Once your have run your MDF through the WebLogic MBeanMaker to generate your intermediate files, and you have edited the MBean implementation file to supply implementations for the appropriate methods within it, you need to package the MBean files and the runtime classes for the custom Role Mapping provider into an MBean JAR File (MJF). The WebLogic MBeanMaker also automates this process.

To create an MJF for your custom Role Mapping provider, follow these steps:

1. Create a new DOS shell.

2. Type the following command:

   java -DMJF=jarfile -Dfiles=filesdir weblogic.management.commo.WebLogicMBeanMaker

   where the -DMJF flag indicates that the WebLogic MBeanMaker should build a JAR file containing the new MBean types, jarfile is the name for the MJF and filesdir is the location where the WebLogic MBeanMaker looks for the files to JAR into the MJF.

   Compilation occurs at this point, so errors are possible. If jarfile is provided, and no errors occur, an MJF is created with the specified name.

Notes: If you want to update an existing MJF, simply delete the MJF and regenerate it. The WebLogic MBeanMaker also has a -DIncludeSource option, which controls whether source files are included into the resulting MJF. Source files include both the generated source and the MDF itself. The default is false. This option is ignored when -DMJF is not used.

The resulting MJF can be installed into your WebLogic Server environment, or distributed to your customers for installation into their WebLogic Server environments.

Install the MBean Type Into the WebLogic Server Environment

To install an MBean type into the WebLogic Server environment, copy the MJF into the WL_HOME\server\lib\mbeantypes directory, where WL_HOME is the top-level installation directory for WebLogic Server. This "deploys" your custom Role Mapping provider—that is, it makes the custom Role Mapping provider manageable from the WebLogic Server Administration Console.

Notes: WL_HOME\server\lib\mbeantypes is the default directory for installing MBean types. However, if you want WebLogic Server to look for MBean types in additional directories, use the -Dweblogic.alternateTypesDirectory=<dir> command-line flag when starting your server, where <dir> is a comma-separated list of directory names. When you use this flag, WebLogic Server will always load MBean types from WL_HOME\server\lib\mbeantypes first, then will look in the additional directories and load all valid archives present in those directories (regardless of their extension). For example, if -Dweblogic.alternateTypesDirectory = dirX,dirY, WebLogic Server will first load MBean types from WL_HOME\server\lib\mbeantypes, then any valid archives present in dirX and dirY.

If you instruct WebLogic Server to look in additional directories for MBean types and are using the Java Security Manager, you must also update the weblogic.policy file to grant appropriate permissions for the MBean type (and thus, the custom security provider). For more information, see "Using the Java Security Manager to Protect WebLogic Resources" in Programming WebLogic Security.

It is advisable to keep non-security provider JARs, including backup files, out of the WL_HOME\server\lib\mbeantypes directory.

You can create instances of the MBean type by configuring your custom Role Mapping provider (see Configure the Custom Role Mapping Provider Using the Administration Console), and then use those MBean instances from a GUI, from other Java code, or from APIs. For example, you can use the WebLogic Server Administration Console to get and set attributes and invoke operations, or you can develop other Java objects that instantiate MBeans and automatically respond to information that the MBeans supply. We recommend that you back up these MBean instances. For more information, see "Backing Up Security Configuration Data" under "Recovering Failed Servers" in Creating and Configuring WebLogic Server Domains.

Configure the Custom Role Mapping Provider Using the Administration Console

Configuring a custom Role Mapping provider means that you are adding the custom Role Mapping provider to your security realm, where it can be accessed by applications requiring role mapping services.

Configuring custom security providers is an administrative task, but it is a task that may also be performed by developers of custom security providers. This section contains information that is important for the person configuring your custom Role Mapping providers:

- Managing Role Mapping Providers and Deployment Descriptors

- Enabling Security Role Deployment

Note: The steps for configuring a custom Role Mapping provider using the WebLogic Server Administration Console are described under "Configuring a Custom Security Provider" in Managing WebLogic Security.

Managing Role Mapping Providers and Deployment Descriptors

Some application components, such as Enterprise JavaBeans (EJBs) and Web applications, store relevant deployment information in Java 2 Enterprise Edition (J2EE) and WebLogic Server deployment descriptors. For Web applications, the deployment descriptor files (called web.xml and weblogic.xml) contain information for implementing the J2EE security model, including security roles. Typically, you will want to include this information when first configuring your Role Mapping providers in the WebLogic Server Administration Console.

The Administration Console provides an Ignore Security Data in Deployment Descriptors check box for this purpose, which you or an administrator should be sure is unchecked the first time a custom Role Mapping provider is configured.

Notes: The Ignore Security Data in Deployment Descriptors check box is unchecked by default. To locate this check box, click Security —> Realms —> realm in the left pane of the Administration Console, where realm is the name of your security realm. Then select the General tab.

When this check box is unchecked and a Web application is deployed, WebLogic Server reads information from the web.xml and weblogic.xml deployment descriptor files (examples of web.xml and weblogic.xml files are shown in Listing 8-4 and Listing 8-5). This information is then copied into the security provider database for the Role Mapping provider.

Listing 8-4 Sample web.xml File

>     <web-app>

>        <welcome-file-list>
>           <welcome-file>welcome.jsp</welcome-file>
>        </welcome-file-list>

>        <security-constraint>
>           <web-resource-collection>
>              <web-resource-name>Success</web-resource-name>
>              <url-pattern>/welcome.jsp</url-pattern>
>              <http-method>GET</http-method>
>              <http-method>POST</http-method>
>           </web-resource-collection>
>           <auth-constraint>
>              <role-name>developers</role-name>
>           </auth-constraint>
>        </security-constraint>

>        <login-config>
>           <auth-method>BASIC</auth-method>
>           <realm-name>default</realm-name>
>        </login-config>

>        <security-role>
>           <role-name>developers</role-name>
>        </security-role>

>     </web-app>

Listing 8-5 Sample weblogic.xml File

>     <weblogic-web-app>
>        <security-role-assignment>
>           <role-name>developers</role-name>
>           <principal-name>myGroup</principal-name>
>        </security-role-assignment>
>     </weblogic-web-app>

While you can set additional security roles in the web.xml/weblogic.xml deployment descriptors and in the Administration Console, BEA recommends that you copy the security roles defined in the Web application deployment descriptors once, then use the Administration Console to define subsequent security roles. This is because any changes made to the seurity roles through the Administration Console during configuration of a Role Mapping provider will not be persisted to the web.xml and weblogic.xml files. Before you deploy the Web application again (which will happen if you redeploy it through the Administration Console, modify it on disk, or restart WebLogic Server), you should check the Ignore Security Data in Deployment Descriptors check box. If you do not, the security roles defined using the Administration Console will be overwritten by those defined in the deployment descriptors. For more information, see "Using the Combined Technique to Secure Your URL (Web) and Enterprise JavaBean (EJB) Resources" in Securing WebLogic Resources.

Notes: The same process applies to EJBs, but with the ejb-jar.xml/weblogic-ejb-jar.xml deployment descriptors.

The Ignore Security Data in Deployment Descriptors check box also affects Authorization providers and Credential Mapping providers. For more information, see Managing Authorization Providers and Deployment Descriptors and Managing Credential Mapping Providers, Resource Adapters, and Deployment Descriptors, respectively.

Enabling Security Role Deployment

If you implemented the DeployableRoleProvider SSPI and want to support deployable security roles with your custom Role Mapping provider, the person configuring the custom Role Mapping provider (that is, you or an administrator) must be sure that the Role Deployment Enabled check box in the WebLogic Server Administration Console is checked. Otherwise, deployment for the Role Mapping provider is considered "turned off." Therefore, if multiple Role Mapping providers are configured, the Role Deployment Enabled check box can be used to control which Role Mapping provider is used for security role deployment.

Note: The Ignore Security Data in Deployment Descriptors check box (specified at the security realm level and described in Managing Role Mapping Providers and Deployment Descriptors) determines whether you want security roles to be copied into the security databases for the configured Role Mapping providers. The Role Deployment Enabled box (specified for each configured Role Mapping provider) determines whether or not the Role Mapping provider is the one that stores the deployed security role.

Provide a Mechanism for Security Role Management

While configuring a custom Role Mapping provider via the WebLogic Server Administration Console makes it accessible by applications requiring role mapping services, you also need to supply administrators with a way to manage this security provider's associated security roles. The WebLogic Role Mapping provider, for example, supplies administrators with a Role Editor page (see Figure 8-2) that allows them to add, modify, or remove security roles for various WebLogic resources. (This page can be found on the Conditions tab for a specific global or scoped role.)

Figure 8-2 WebLogic Role Mapping Provider's Role Editor Page

Neither the Role Editor page nor access to it is available to administrators when you develop a custom Role Mapping provider. Therefore, you must provide your own mechanism for security role management. This mechanism must read and write security role data (that is, expressions) to and from the custom Role Mapping provider's database.

You can accomplish this task in one of three ways:

- Option 1: Create Your Own "Role Editor" Page Using Console Extensions

- Option 2: Develop a Stand-Alone Tool for Security Role Management

- Option 3: Integrate an Existing Security Role Management Tool into the Administration Console

Option 1: Create Your Own "Role Editor" Page Using Console Extensions

The main benefit of creating console extensions for your custom Role Mapping provider is that the console extension provides you with the ID for the WebLogic resource and therefore, the WebLogic resource's location in the resource hierarchy. (This information is required to read and write expressions to and from the Role Mapping provider's database.) An additional benefit is that your page can be integrated into the existing WebLogic Server Administration Console GUI, like the Role Editor page provided with the WebLogic Role Mapping provider.

If you selected this option, you need to:

1. Implement the getExtensionForRole() method of the weblogic.management.console.extensibility.SecurityExtension interface, and have this method return your Role Editor page.

   Note: For more information, see Writing Console Extensions for Custom Security Providers.

2. In addition, you must do one of the following:

   1. Implement the RoleEditor and RoleReader optional Authorization SSPI MBeans to develop a management MBean that will act as an intermediary between your Role Editor page and the Role Mapping provider's database. For more information, see Determine Which SSPI MBeans to Extend and Implement and Table 2-4.

      In this case, you also need to develop a syntax for the expressions that make up a security role that can be represented as a string. (For example, Role=Admin or Group=Administrators.)

      Note: This syntax can be different for different Role Mapping providers. For more information about expressions, see "Components of a Security Role: Role Conditions, Expressions, and Role Statements" in Securing WebLogic Resources.

   2. Develop your own MBean APIs for managing security roles, and implement those interfaces to develop a management MBean that will act as an intermediary between your Role Editor page and the Role Mapping provider's database.

   3. Read and write the expressions from and to the custom Role Mapping provider's database directly, without delegating to an MBean.

Option 2: Develop a Stand-Alone Tool for Security Role Management

You would typically select this option if you want to develop a tool that is entirely separate from the WebLogic Server Administration Console.

For this option, you do not need to write any console extensions for your custom Role Mapping provider, nor do you need to develop any management MBeans as described in Option 1: Create Your Own "Role Editor" Page Using Console Extensions. However, your tool needs to:

1. Determine the WebLogic resource's ID, since it is not automatically provided to you by the console extension. For more information, see WebLogic Resource Identifiers.

2. Determine how to represent the expressions that make up a security role. (This representation is entirely up to you and need not be a string as in Option 1: Create Your Own "Role Editor" Page Using Console Extensions)

3. Read and write the expressions from and to the custom Role Mapping provider's database.

Option 3: Integrate an Existing Security Role Management Tool into the Administration Console

You would typically select this option if you have a tool that is separate from the WebLogic Server Administration Console, but you want to launch that tool from the Administration Console.

For this option, your tool needs to:

1. Determine the WebLogic resource's ID, since it is not automatically provided to you by the console extension. For more information, see WebLogic Resource Identifiers.

2. Determine how to represent the expressions that make up a security role. (This representation is entirely up to you and need not be a string as in Option 1: Create Your Own "Role Editor" Page Using Console Extensions)

3. Read and write the expressions from and to the custom Role Mapping provider's database.

4. Link into the Administration Console using basic console extension techniques, as described in Extending the Administration Console.