Developing Security Providers
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Careful planning of development activities can greatly reduce the time and effort you spend developing custom security providers. The following sections provide information to help you make design decisions and to understand the process and components of the custom security provider development:
Although you can develop different types of security providers, all security providers follow the same general architecture. Figure 3-1 illustrates the general architecture of a security provider.
Figure 3-1 Security Provider Architecture
Figure 3-1 shows the relationship between a single runtime class (MyFooProviderImpl
) and an MBean type (MyFooMBean
) file. To develop a custom security provider you write an MBean Definition File, the MyFooMBean
MBean type file. The MyFooBean
file extends the SSPI MBean (FooSSPIMBean
). It is written in XML format. When you run the MBean Definition File through the WebLogic MBeanMaker, that utility generates the runtime class for the MBean type, MyFooMBean.java
.
The process begins when a Security Service Module instance starts and the Security Framework:
You develop a custom security provider by first implementing the security service provider interface to create runtime classes. See Types of Providers for a list of which one to implement for each type of security provider.
Each SSPI that ends in the suffix "Provider
" (for example, CredentialProvider
) exposes the services of a security provider to the Security Framework. This allows you to manipulate the security provider (initialize, start, stop, and so on).
Figure 3-2 shows the SSPI provided with BEA WebLogic Enterprise Security. This SSPI extends the Security Provider interface (SecurityProvider.java
) and its methods and exposes the security services to the framework. Because the custom security provider runtime classes implement a Security Provider interface, all such runtime classes must provide implementations for these inherited methods. Table 3-1 describes the security provider interface methods.
This method takes two arguments: The The |
|
Returns a brief textual description of the custom security provider. |
|
To develop a custom security provider, you must create runtime classes that implement the security provider SSPI. Using a Credential Mapping provider as an example, Figure 3-3 illustrates the inheritance hierarchy that is common to all SSPIs and shows how a runtime class, can implement the required interfaces. In this example, BEA supplies the SecurityProvider
interface and the CredentialProvider
and CredentialMapper
SSPI. A single runtime class, MyCredentialMapperProviderImpl
, implements the CredentialProvider
and CredentialMapper
SSPI.
Figure 3-3 Credential Mapping SSPI and a Single Runtime Class
However, Figure 3-3 illustrates only one way you can implement the SSPI, that is, by creating a single runtime class. If you prefer, as illustrated in Figure 3-4, you can create two runtime classes: one for the implementation of the Provider SSPI (for example, the CredentialProvider
) and one for the implementation of the other SSPI (for example, the CredentialMapper
SSPI).
When you choose to create two runtime classes, the class that implements the Provider SSPI acts as a factory for generating an instance of the runtime class that implements the other SSPI. For example, in Figure 3-4, MyCredentialMapperProviderImpl
acts as a factory for generating MyCredentialMapperImpl
.
Note: If you choose to create two runtime classes, remember to include both of them in the MBean JAR File when you use the WebLogic MBeanMaker to generate the security provider MBean type.
Figure 3-4 Credential Mapping SSPI and Two Runtime Classes
BEA WebLogic Enterprise Security provides an extended version of the standard WebLogic Security Service Provider Interface (SSPI). Providers that you write to work in both environments must handle both WebLogic resources and extended ones. Listing 3-1 shows how to use the instanceof
operator in providers to check for extended resource
.
Listing 3-1 Adding Code to Providers to Check for Extended Resource
if ( myresource instanceof com.bea.security.spi.ResourceActionBundle ) {
// This is a WLES resource that uses the enhanced SSPI.
} else {
// This is a WLS resource. You must test further for more object
// types and handle them explicitly.
}
The com.bea.security.spi.ResourceActionBundle
interface is a representation of a resource. As the name implies, this interface is merely a container for two other objects, ProviderResource
and ProviderAction
. ProviderResource
is the resource portion of this object and ProviderAction
is the action. The security provider understands which object is the operand and which is the verb.
A ProviderResource
object gives the provider a mechanism to parse this resource name without having to understand the intricacies of the specific format. The ProviderResource.getDeepEnumeration()
method extracts a collection of NameValueTypes
that can may be mapped into the internal representation of the provider for that resource.
The ProviderResource
.getEnumeration()
method is another method that provides a set of ordered NameValueTypes
, however, this method provides a shallow enumeration, breaking the resource into more coarsely grained pieces. How this resource is parsed is determined by the application developer by means of a naming authority.
A resource type directly relates to its naming authority. A resource that has a naming authority of "HR_URL
" is considered a different kind of resource than one who has a naming authority of "INTERNET_URL
," even if both resources map to the same keys and values. You can get the name of a resource's naming authority with the ProviderResource.getAuthorityName()
method.
Additionally, a ProviderResource
object can also return a reference to its parent resource (ProviderResource.getResourceParent()
method), if available. Therefore, a provider does not have to know how to produce a parent from the resource; in fact, the resource and the action can have separate parents.
A ProviderAction
object is very similar to a ProviderResource
. It can be enumerated, parented, and linked to its own naming authority name as well.
BEA WebLogic Enterprise Security provides an extended version of the standard WebLogic Security Service Provider Interface (SSPI). Providers that you write to work in both environments must handle both WebLogic audit records and extended ones. Listing 3-2 shows how to use the instanceof
operator in providers to check for extended audit records.
Listing 3-2 Adding Code to Providers to Check for an Extended Audit Record
if ( myauditrecord instanceof com.bea.security.spi.ProviderAuditRecord) {
// This is a WLESaudit record
that uses the enhanced SSPI.
} else {
// This is a WLSaudit record
. You must test further for more object
// types and handle them explicitly.
}
A simple audit provider can use the toString
() method to render the audit record as a string; thus, the provider does not require specific knowledge of the audit record type.
A more complex auditing provider that tracks events by many keys and needs to distinguish messages by various types and attributes, requires a data-driven method of event introspection. The Provider Audit Record Interface, com.bea.security.spi.ProviderAuditRecord
, satisfies this requirement.
This interface addresses this requirement by employing a similar mechanism as is used to inspect resources. An audit event can be enumerated using the ProviderAuditRecord
.getEnumeration()
and getDeepEnumeration()
methods.
Additionally, the Provider Audit Record interface can associate an application context with an audit event.
This allows the auditing provider to select some context elements to audit when events occur. For example, when an audit event occurs, you may choose to audit the number of concurrent sessions, the time the user logged on, or some other application specific value propagated by the application context.
The next task in developing a custom security provider is generating an MBean type for the custom security provider.
In addition to creating runtime classes for a custom security provider, you must also generate an MBean type. The term MBean is short for managed bean, a Java object that represents a Java Management eXtensions (JMX) manageable resource. MBeans are used to expose configuration to the provider runtime class.
Note: JMX is a specification created by Sun Microsystems that defines a standard management architecture, APIs, and management services. For more information, see the Java Management Extensions White Paper.
You use MBean interfaces called SSPI MBeans to create MBean types. Based on the custom security provider you plan to develop, refer to Table 3-2 and locate the required SSPI MBean.
An MBean Definition File is an XML file used by the WebLogic MBeanMaker utility to generate the Java files that comprise an MBean type. All MBean Definition Files must extend a required SSPI MBean that is specific to the type of the security provider you have created. Listing 3-3 shows a sample MBean Definition File and an explanation of its content follows.
Note: For a complete reference of MBean Definition File element syntax, see MBean Definition File Element Syntax.
Listing 3-3 SampleCredentialMapper.xml
<?xml version="1.0" ?>
<!DOCTYPE MBeanType SYSTEM "commo.dtd">
<!-- MBean Definition File (MDF) for the Sample Credential Mapper.
Copyright (c) 2003 by BEA Systems, Inc. All Rights Reserved.
-->
<!-- Declare your mbean.
Since it is for an credential mapper, it must extend the
weblogic.management.security.credentials.CredentialMapper or
weblogic.management.security.credentials.DeployableCredentialMapper
mbean.
Since this sample supports WLS RA deployments, it extends the
weblogic.management.security.credentials.DeployableCredentialMapper
mbean.
The Name and DisplayName must be the same.
They specify the name that will appear on the
console for this provider.
Note that since this is an xml document, you can't use double
quotes directly. Instead you need to use "
Note that setting "Writeable" to "false" on an attribute
makes the attribute read-only. The default is read-write.
-->
<MBeanType
Name = "SampleCredentialMapper"
DisplayName = "SampleCredentialMapper"
Package = "examples.security.providers.credentials"
Extends = "weblogic.management.security.credentials.DeployableCredentialMapper"
>
<!-- You must set the value of the ProviderClassName attribute
(inherited from the weblogic.management.security.Provider mbean)
to the name of the java class you wrote that implements the
weblogic.security.spi.CredentialProvider or
weblogic.security.spi.DeployableCredentialProvider interface.
Since this sample supports WLS RA deployments, it implements
the weblogic.security.spi.DeployableCredentialProvider interface.
You can think of the provider's mbean as the factory
for your provider's runtime implementation.
-->
<MBeanAttribute
Name = "ProviderClassName"
Type = "java.lang.String"
Writeable = "false"
Default =
""examples.security.providers.credentials.SampleCredentialMapperProviderImpl""
/>
<!-- You must set the value of the Description attribute
(inherited from the weblogic.management.security.Provider mbean)
to a brief description of your provider.
It is displayed in the console.
-->
<MBeanAttribute
Name = "Description"
Type = "java.lang.String"
Writeable = "false"
Default = ""WLES Sample Credential Mapper Provider""
/>
<!-- You must set the value of the Version attribute
(inherited from the weblogic.management.security.Provider mbean)
to your provider's version. There is no required format.
-->
<MBeanAttribute
Name = "Version"
Type = "java.lang.String"
Writeable = "false"
Default = ""1.0""
/>
<!-- Add any custom attributes for your provider here.
The sample credential mapper does not have any custom attributes.
-->
</MBeanType>
The bold
attributes in the <MBeanType>
tag show that this MBean Definition File is named SampleCredentialMapper
and that it extends the required SSPI MBean called DeployableCredentialMapper.
The ProviderClassName
, Description
, and Version
attributes defined in the <MBeanAttribute>
tags are required in any MBean Definition File used to generate MBean types for security providers because they define the basic configuration methods for the provider and are inherited from the base required SSPI MBean called Provider
(see Figure 3-6). The ProviderClassName
attribute is especially important. The value for the ProviderClassName
attribute is the name of the security provider runtime class (that is, the implementation of the appropriate SSPI). The example runtime class shown in Listing 3-3 is SampleCredentialMapperProviderImpl.java
.
While not shown in Listing 3-3, you can include additional attributes in an MBean Definition File using the <MBeanAttribute>
tag. Most custom attributes automatically appear in the Details tab for your custom security provider in the Administration Application (as shown in Figure 3-5).
Figure 3-5 Database Credential Mapping Provider Details Tab
All attributes specified in the required SSPI MBeans that your MBean Definition File extends (all the way up to the Provider
base SSPI MBean) automatically appear in a Administration Application pages for the associated security provider. You use these attributes to configure your custom security providers. Figure 3-6 illustrates the SSPI MBean hierarchy for security providers using the Sample Credential Mapping MBean Definition File as an example.
Figure 3-6 SSPI MBean Hierarchy for Credential Mapping Providers
Implementing the hierarchy of SSPI MBeans in the Sample Credential Mapper MBean Definition File (shown in Figure 3-6) produces the page in the Administration Application that is shown in Figure 3-7. The full listing of the Sample Credential Mapper MBean Definition File is shown in Listing 3-2.
Figure 3-7 Sample Credential Mapper General Tab
The Name, Description, and Version fields are derived from attributes with the same names, inherited from the base required SSPI MBean called Provider
and specified in the Sample Credential Mapper MBean Definition File. The DisplayName
attribute in the Sample Credential Mapper MBean Definition File generates the value for the Name field, and that the Description
and Version
attributes generate the values for their respective fields as well.
The WebLogic MBeanMaker is a command-line utility that takes an MBean Definition File as input and outputs an MBean Java interface. This Java interface can then be used in the custom security provider runtime class, through the weblogic.security.spi.SecurityProvider.initialize()
method, to get configuration attributes. Figure 3-8 shows the operations performed by the WebLogic MBeanMaker utility.
Figure 3-8 What the WebLogic MBeanMaker Provides
You must initialize the security provider database with the default users, groups, security policies, security roles, or credentials that your providers need. The provider is not restricted to using a relational database. A provider can store users, groups, etc., in a variety of persistent stores as described in the Introduction to WebLogic Enterprise Security.
The first time you use a custom provider, it attempts to locate a database with the information needed to provide its security service. If the security provider fails to locate the database, it need to create one and populate it with the default users, groups, security policies, security roles, and credentials. This option may be useful for development and testing purposes.
Note: The sample security providers, available under Code Samples:WebLogic Enterprise Security on the dev2dev Web site, simply create and use a properties file as their database. For example, the sample Authentication provider creates a properties file that contains the necessary information about users and groups.
If you already have a database (such as an external LDAP server), you can populate that database with the users, groups, security policies, security roles, and credentials that your providers require. Populating an existing database is accomplished using whatever tools you already have in place for performing these tasks. For information on setting up an external repository see, Configuring Metadirectories in the Administration Application Installation Guide.
Once your database contains the necessary information, you must configure the security providers to look in that database. You accomplish this by adding custom attributes in your MBean Definition File. Some examples of custom attributes are the database host, port, password, and so on. You can use the Administration Application to configure these attributes to point to the database.
As an example, Listing 3-4 shows some custom attributes that are part of the LDAP Authentication provider MBean Definition File. These attributes allow an administrator to specify information about the LDAP Authentication provider database (an external LDAP server), so it can locate information about users and groups.
Listing 3-4 LDAPAuthenticator.xml
...<MBeanAttribute
Name = "UserObjectClass"
Type = "java.lang.String"
Default = ""person""
Description = "The LDAP object class that stores users."
/>
<MBeanAttribute
Name = "UserNameAttribute"
Type = "java.lang.String"
Default = ""uid""
Description = "The attribute of an LDAP user object that specifies the name of
the user."
/>
<MBeanAttribute
Name = "UserDynamicGroupDNAttribute"
Type = "java.lang.String"
Description = "The attribute of an LDAP user object that specifies the
distinguished names (DNs) of dynamic groups to which this user belongs.
If such an attribute does not exist, WebLogic Server determines if a
user is a member of a group by evaluating the URLs on the dynamic group.
If a group contains other groups, the URLs are evaluated for
any of the descendents of the group."
/>
<MBeanAttribute
Name = "UserBaseDN"
Type = "java.lang.String"
Default = ""ou=people, o=example.com""
Description = "The base distinguished name (DN) of the tree in the LDAP directory that contains users."
/>
<MBeanAttribute
Name = "UserSearchScope"
Type = "java.lang.String"
Default = ""subtree""
LegalValues = "subtree,onelevel"
Description = "Specifies how deep in the LDAP directory tree to search
for Users.
Valid values are <code>subtree</code>
and <code>onelevel</code>."
/>
...
If possible, initialization calls between a security provider and the security provider database are done by an intermediary class, referred to as a database delegator. Use of a database delegator is convenient because it hides the database and centralizes calls into the database. The database delegator should interact with the runtime class and the MBean type for the security provider, as shown in Figure 3-9.
Figure 3-9 Database Delegator Class Positioning
![]() ![]() |
![]() |
![]() |