e-docs > WebLogic Server > Developing Security Providers for WebLogic Server > Authentication Providers |
Developing Security Providers for WebLogic Server |
Authentication is the mechanism by which callers prove that they are acting on behalf of specific users or systems. Authentication answers the question, "Who are you?" using credentials such as username/password combinations.
In WebLogic Server, Authentication providers are used to prove the identity of users or system processes. Authentication providers also remember, transport, and make that identity information available to various components of a system (via subjects) when needed. During the authentication process, a Principal Validation provider provides additional security protections for the principals (users and groups) contained within the subject by signing and verifying the authenticity of those principals. (For more information, see Principal Validation Providers.)
The following sections describe Authentication provider concepts and functionality, and provide step-by-step instructions for developing a custom Authentication provider:
Note: An Identity Assertion provider is a specific form of Authentication provider that allows users or system processes to assert their identity using tokens. For more information, see Identity Assertion Providers.
Before delving into the specifics of developing custom Authentication providers, it is important to understand the following concepts:
Users and Groups, Principals and Subjects
A user is similar to an operating system user in that it represents a person. A group is a category of users, classified by common traits such as job title. Categorizing users into groups makes it easier to control the access permissions for large numbers of users. For more information about users and groups, see "Users and Groups" in Securing WebLogic Resources.
Both users and groups can be used as principals by application servers like WebLogic Server. A principal is an identity assigned to a user or group as a result of authentication. The Java Authentication and Authorization Service (JAAS) requires that subjects be used as containers for authentication information, including principals. Each principal stored in the same subject represents a separate aspect of the same user's identity, much like cards in a person's wallet. (For example, an ATM card identifies someone to their bank, while a membership card identifies them to a professional organization to which they belong.) For more information about JAAS, see Java Authentication and Authorization Service (JAAS).
Note: Subjects replace WebLogic Server 6.x users.
Figure 3-1 illustrates the relationships among users, groups, principals, and subjects.
Figure 3-1 Relationships Among Users, Groups, Principals and Subjects
As part of a successful authentication, principals are signed and stored in a subject for future use. A Principal Validation provider signs principals, and an Authentication provider's LoginModule actually stores the principals in the subject. Later, when a caller attempts to access a principal stored within a subject, a Principal Validation provider verifies that the principal has not been altered since it was signed, and the principal is returned to the caller (assuming all other security conditions are met).
Note: For more information about Principal Validation providers and LoginModules, see Principal Validation Providers and LoginModules, respectively.
Any principal that is going to represent a WebLogic Server user or group needs to implement the WLSUser and WLSGroup interfaces, which are available in the weblogic.security.spi package.
A LoginModule is a required component of an Authentication provider, and can be a component of an Identity Assertion provider if you want to develop a separate LoginModule for perimeter authentication.
LoginModules are the work-horses of authentication: all LoginModules are responsible for authenticating users within the security realm and for populating a subject with the necessary principals (users/groups). LoginModules that are not used for perimeter authentication also verify the proof material submitted (for example, a user's password).
Note: For more information about Identity Assertion providers and perimeter authentication, see Identity Assertion Providers.
If there are multiple Authentication providers configured in a security realm, each of the Authentication providers' LoginModules will store principals within the same subject. Therefore, if a principal that represents a WebLogic Server user (that is, an implementation of the WLSUser interface) named "Joe" is added to the subject by one Authentication provider's LoginModule, any other Authentication provider in the security realm should be referring to the same person when they encounter "Joe". In other words, the other Authentication providers' LoginModules should not attempt to add another principal to the subject that represents a WebLogic Server user (for example, named "Joseph") to refer to the same person. However, it is acceptable for a another Authentication provider's LoginModule to add a principal of a type other than WLSUser with the name "Joseph".
LoginModules can be written to handle a variety of authentication mechanisms, including username/password combinations, smart cards, biometric devices, and so on. You develop LoginModules by implementing the javax.security.auth.spi.LoginModule interface, which is based on the Java Authentication and Authorization Service (JAAS) and uses a subject as a container for authentication information. The LoginModule interface enables you to plug in different kinds of authentication technologies for use with a single application, and the WebLogic Security Framework is designed to support multiple LoginModule implementations for multipart authentication. You can also have dependencies across LoginModule instances or share credentials across those instances. However, the relationship between LoginModules and Authentication providers is one-to-one. In other words, to have a LoginModule that handles retina scan authentication and a LoginModule that interfaces to a hardware device like a smart card, you must develop and configure two Authentication providers, each of which include an implementation of the LoginModule interface. For more information, see Implement the JAAS LoginModule Interface.
Note: You can also obtain LoginModules from third-party security vendors instead of developing your own.
LoginModules and Multipart Authentication
The way you configure multiple Authentication providers (and thus, multiple LoginModules) can affect the overall outcome of the authentication process, which is especially important for multipart authentication. First, because LoginModules are components of Authentication providers, they are called in the order in which the Authentication providers are configured. Generally, you configure Authentication providers using the WebLogic Server Administration Console. (For more information, see Configure the Custom Authentication Provider Using the Administration Console.) Second, the way each LoginModule's control flag is set specifies how a failure during the authentication process should be handled. Figure 3-2 illustrates a sample flow involving three different LoginModules (that are part of three Authentication providers), and illustrates what happens to the subject for different authentication outcomes.
Figure 3-2 Sample LoginModule Flow
If the control flag for Custom Authentication Provider #1 had been set to Required, the authentication failure in its User Authentication step would have caused the entire authentication process to have failed. Also, if the user had not been authenticated by the WebLogic Authentication provider (or custom Authentication provider #2), the entire authentication process would have failed. If the authentication process had failed in any of these ways, all three LoginModules would have been rolled back and the subject would not contain any principals.
Note: For more information about the LoginModule control flag setting and the LoginModule interface, see the Java Authentication and Authorization Service (JAAS) 1.0 LoginModule Developer's Guide and the Java 2 Enterprise Edition, v1.3.1 API Specification Javadoc for the LoginModule interface, respectively.
Java Authentication and Authorization Service (JAAS)
Whether the client is an application, applet, Enterprise JavaBean (EJB), or servlet that requires authentication, WebLogic Server uses the Java Authentication and Authorization Service (JAAS) classes to reliably and securely authenticate to the client. JAAS implements a Java version of the Pluggable Authentication Module (PAM) framework, which permits applications to remain independent from underlying authentication technologies. Therefore, the PAM framework allows the use of new or updated authentication technologies without requiring modifications to your application.
WebLogic Server uses JAAS for remote fat-client authentication, and internally for authentication. Therefore, only developers of custom Authentication providers and developers of remote fat client applications need to be involved with JAAS directly. Users of thin clients or developers of within-container fat client applications (for example, those calling an Enterprise JavaBean (EJB) from a servlet) do not require the direct use or knowledge of JAAS.
How JAAS Works With the WebLogic Security Framework
Generically, authentication using the JAAS classes and WebLogic Security Framework is performed in the following manner:
Notes: A CallbackHandler is a highly-flexible JAAS standard that allows a variable number of arguments to be passed as complex objects to a method. There are three types of CallbackHandlers: NameCallback, PasswordCallback, and TextInputCallback, all of which reside in the javax.security.auth.callback package. The NameCallback and PasswordCallback return the username and password, respectively. TextInputCallback can be used to access the data users enter into any additional fields on a login form (that is, fields other than those for obtaining the username and password). When used, there should be one TextInputCallback per additional form field, and the prompt string of each TextInputCallback must match the field name in the form. WebLogic Server only uses the TextInputCallback for form-based Web application login. For more information about CallbackHandlers, see the Java 2 Enterprise Edition, v1.4.0 API Specification Javadoc for the CallbackHandler interface.
For more information about the LoginContext class, see the Java 2 Enterprise Edition v1.3.1 Specification Javadoc for the LoginContext class.
For more information about the UsernamePasswordLoginModule, see the WebLogic Server 7.0 API Reference Javadoc for the UsernamePasswordLoginModule class.
If you do not want to use a client-side LoginModule, you can specify the username and password in other ways: for example, as part of the initial JNDI lookup.
Note: For more information about LoginModules, see LoginModules.
The LoginModule attempts to authenticate the client using the authentication information.
Note: For authentication performed entirely on the server-side, the process would begin at step 3, and the WebLogic Server container would call the weblogic.security.services.authentication.login method prior to step 4. (The weblogic.security.services.authentication.login method is only available in WebLogic Server 7.0 SP01.)
Example: Standalone T3 Application
Figure 3-3 illustrates how the JAAS classes work with the WebLogic Security Framework for a standalone, T3 application, and an explanation follows.
Figure 3-3 Authentication Using JAAS Classes and WebLogic Server
For this example, authentication using the JAAS classes and WebLogic Security Framework is performed in the following manner:
Note: The weblogic.security.auth.login.UsernamePasswordLoginModule implements the standard JAAS javax.security.auth.spi.LoginModule interface and uses client-side APIs to authenticate a WebLogic client to a WebLogic Server instance. It can be used for both T3 and IIOP clients. Callers of this LoginModule must implement a CallbackHandler to pass the username (NameCallback), password (PasswordCallback), and a URL (URLCallback).
The LoginModule attempts to authenticate the client using the authentication information.
Figure 3-4 shows a behind-the-scenes look of the authentication process for a fat-client login. JAAS runs on the server to perform the login. Even in the case of a thin-client login (that is, a browser client) JAAS is still run on the server.
Figure 3-4 The Authentication Process
Notes: Only developers of custom Authentication providers will be involved with this JAAS process directly. The client application could either use JNDI initial context creation or JAAS to initiate the passing of the username and password.
When a user attempts to log into a system using a username/password combination, WebLogic Server establishes trust by validating that user's username and password, and returns a subject that is populated with principals per JAAS requirements. As Figure 3-4 also shows, this process requires the use of a LoginModule and a Principal Validation provider, which are discussed in detail in LoginModules and Principal Validation Providers, respectively.
After successfully proving a caller's identity, an authentication context is established, which allows an identified user or system to be authenticated to other entities. Authentication contexts may also be delegated to an application component, allowing that component to call another application component while impersonating the original caller.
Do You Need to Develop a Custom Authentication Provider?
The default (that is, active) security realm for WebLogic Server includes a WebLogic Authentication provider.
Note: In conjunction with the WebLogic Authorization provider, the WebLogic Authentication provider replaces the functionality of the File realm that was available in 6.x releases of WebLogic Server.
The WebLogic Authentication provider supports delegated username/password authentication, and utilizes an embedded LDAP server to store user and group information. The WebLogic Authentication provider allows you to edit, list, and manage users and group membership. If you want to perform additional authentication tasks, then you need to develop a custom Authentication provider.
Note: If you want to perform perimeter authentication using X509 certificates or CORBA Common Secure Interoperability version 2 (CSIv2), you might need to develop a custom Identity Assertion provider. For more information, see Identity Assertion Providers.
How to Develop a Custom Authentication Provider
If the WebLogic Authentication provider does not meet your needs, you can develop a custom Authentication provider by following these steps:
Create Runtime Classes Using the Appropriate SSPIs
Before you start creating runtime classes, you should first:
When you understand this information and have made your design decisions, create the runtime classes for your custom Authentication provider by following these steps:
For an example of how to create a runtime class for a custom Authentication provider, see Example: Creating the Runtime Classes for the Sample Authentication Provider.
Implement the AuthenticationProvider SSPI
To implement the AuthenticationProvider SSPI, provide implementations for the methods described in Understand the Purpose of the "Provider" SSPIs and the following methods:
Note: The implementation of the getAssertionModuleConfiguration method can be to return null, if you want the Identity Assertion provider to use the same LoginModule as the Authentication provider.
For more information about the AuthenticationProvider SSPI and the methods described above, see the WebLogic Server 7.0 API Reference Javadoc.
Implement the JAAS LoginModule Interface
To implement the JAAS javax.security.auth.spi.LoginModule interface, provide implementations for the following methods:
Note: The LoginModule.logout method is never called for the WebLogic Authentication providers or custom Authentication providers. This is simply because once the principals are created and placed into a subject, the WebLogic Security Framework no longer controls the lifecycle of the subject. Therefore, the developer-written, user code that creates the JAAS LoginContext to login and obtain the subject should also call the LoginContext.logout method. When the user code runs in a Java client that uses JAAS directly, that code has the option of calling the LoginContext.logout method, which clears the subject. When the user code runs in a servlet, the servlet has the ability to logout a user from a servlet session, which clears the subject.
For more information about the JAAS LoginModule interface and the methods described above, see the Java Authentication and Authorization Service (JAAS) 1.0 Developer's Guide, and the Java 2 Enterprise Edition, v1.3.1 API Specification Javadoc for the LoginModule interface.
Throwing Custom Exceptions from LoginModules
You may want to throw a custom exception from a LoginModule you write. The custom exception can then be caught by your application and appropriate action taken. For example, if a PasswordChangeRequiredException is thrown from your LoginModule, you can catch that exception within your application, and use it to forward users to a page that allows them to change their password.
When you throw a custom exception from a LoginModule and want to catch it within your application, you must ensure that:
Method 1: Make Custom Exceptions Available via the System and Compiler Classpath
Method 2: Make Custom Exceptions Available via the Application Classpath
Example: Creating the Runtime Classes for the Sample Authentication Provider
Listing 3-1 shows the SampleAuthenticationProviderImpl.java class, which is one of two runtime classes for the sample Authentication provider. This runtime class includes implementations for:
Note: The bold face code in Listing 3-1 highlights the class declaration and the method signatures.
Listing 3-1 SampleAuthenticationProviderImpl.java
package examples.security.providers.authentication;
import java.util.HashMap;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import weblogic.management.security.ProviderMBean;
import weblogic.security.provider.PrincipalValidatorImpl;
import weblogic.security.spi.AuthenticationProvider;
import weblogic.security.spi.IdentityAsserter;
import weblogic.security.spi.PrincipalValidator;
import weblogic.security.spi.SecurityServices;
public final class SampleAuthenticationProviderImpl implements AuthenticationProvider
{
private String description;
private SampleAuthenticatorDatabase database;
private LoginModuleControlFlag controlFlag;
public void initialize(ProviderMBean mbean, SecurityServices services)
{
System.out.println("SampleAuthenticationProviderImpl.initialize");
SampleAuthenticatorMBean myMBean = (SampleAuthenticatorMBean)mbean;
description = myMBean.getDescription() + "\n" + myMBean.getVersion();
database = new SampleAuthenticatorDatabase(myMBean);
String flag = myMBean.getControlFlag();
if (flag.equalsIgnoreCase("REQUIRED")) {
controlFlag = LoginModuleControlFlag.REQUIRED;
} else if (flag.equalsIgnoreCase("OPTIONAL")) {
controlFlag = LoginModuleControlFlag.OPTIONAL;
} else if (flag.equalsIgnoreCase("REQUISITE")) {
controlFlag = LoginModuleControlFlag.REQUISITE;
} else if (flag.equalsIgnoreCase("SUFFICIENT")) {
controlFlag = LoginModuleControlFlag.SUFFICIENT;
} else {
throw new IllegalArgumentException("invalid flag value" + flag);
}
}
public String getDescription()
{
return description;
}
public void shutdown()
{
System.out.println("SampleAuthenticationProviderImpl.shutdown");
}
private AppConfigurationEntry getConfiguration(HashMap options)
{
options.put("database", database);
return new
AppConfigurationEntry(
"examples.security.providers.authentication.SampleLoginModuleImpl",
controlFlag,
options
);
}
public AppConfigurationEntry getLoginModuleConfiguration()
{
HashMap options = new HashMap();
return getConfiguration(options);
}
public AppConfigurationEntry getAssertionModuleConfiguration()
{
HashMap options = new HashMap();
options.put("IdentityAssertion","true");
return getConfiguration(options);
}
public PrincipalValidator getPrincipalValidator()
{
return new PrincipalValidatorImpl();
}
public IdentityAsserter getIdentityAsserter()
{
return null;
}
}
Listing 3-2 shows the SampleLoginModuleImpl.java class, which is one of two runtime classes for the sample Authentication provider. This runtime class implements the JAAS LoginModule interface (as described in Implement the JAAS LoginModule Interface), and therefore includes implementations for its initialize, login, commit, abort, and logout methods.
Note: The bold face code in Listing 3-2 highlights the class declaration and the method signatures.
Listing 3-2 SampleLoginModuleImpl.java
package examples.security.providers.authentication;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.spi.LoginModule;
import weblogic.management.utils.NotFoundException;
import weblogic.security.spi.WLSGroup;
import weblogic.security.spi.WLSUser;
import weblogic.security.principal.WLSGroupImpl;
import weblogic.security.principal.WLSUserImpl;
final public class SampleLoginModuleImpl implements LoginModule
{
private Subject subject;
private CallbackHandler callbackHandler;
private SampleAuthenticatorDatabase database;
// Determine whether this is a login or assert identity
private boolean isIdentityAssertion;
// Authentication status
private boolean loginSucceeded;
private boolean principalsInSubject;
private Vector principalsForSubject = new Vector();
public void initialize(Subject subject, CallbackHandler callbackHandler, Map
sharedState, Map options)
{
// only called (once!) after the constructor and before login
System.out.println("SampleLoginModuleImpl.initialize");
this.subject = subject;
this.callbackHandler = callbackHandler;
// Check for Identity Assertion option
isIdentityAssertion =
"true".equalsIgnoreCase((String)options.get("IdentityAssertion"));
database = (SampleAuthenticatorDatabase)options.get("database");
}
public boolean login() throws LoginException
{
// only called (once!) after initialize
System.out.println("SampleLoginModuleImpl.login");
// loginSucceeded should be false
// principalsInSubject should be false
// user should be null
// group should be null
Callback[] callbacks = getCallbacks();
String userName = getUserName(callbacks);
if (userName.length() > 0) {
if (!database.userExists(userName)) {
throwFailedLoginException("Authentication Failed: User " + userName
+ " doesn't exist.");
}
if (!isIdentityAssertion) {
String passwordWant = null;
try {
passwordWant = database.getUserPassword(userName);
} catch (NotFoundException shouldNotHappen) {}
String passwordHave = getPasswordHave(userName, callbacks);
if (passwordWant == null || !passwordWant.equals(passwordHave)) {
throwFailedLoginException(
"Authentication Failed: User " + userName + " bad password. " +
"Have " + passwordHave + ". Want " + passwordWant + "."
);
}
}
} else {
// anonymous login - let it through?
System.out.println("\tempty userName");
}
loginSucceeded = true;
principalsForSubject.add(new WLSUserImpl(userName));
addGroupsForSubject(userName);
return loginSucceeded;
}
public boolean commit() throws LoginException
{
// only called (once!) after login
// loginSucceeded should be true or false
// principalsInSubject should be false
// user should be null if !loginSucceeded, null or not-null otherwise
// group should be null if user == null, null or not-null otherwise
System.out.println("SampleLoginModule.commit");
if (loginSucceeded) {
subject.getPrincipals().addAll(principalsForSubject);
principalsInSubject = true;
return true;
} else {
return false;
}
}
public boolean abort() throws LoginException
{
// The abort method is called to abort the authentication process. This is
// phase 2 of authentication when phase 1 fails. It is called if the
// LoginContext's overall authentication failed.
// loginSucceeded should be true or false
// user should be null if !loginSucceeded, otherwise null or not-null
// group should be null if user == null, otherwise null or not-null
// principalsInSubject should be false if user is null, otherwise true
// or false
System.out.println("SampleLoginModule.abort");
if (principalsInSubject) {
subject.getPrincipals().removeAll(principalsForSubject);
principalsInSubject = false;
}
return true;
}
public boolean logout() throws LoginException
{
// should never be called
System.out.println("SampleLoginModule.logout");
return true;
}
private void throwLoginException(String msg) throws LoginException
{
System.out.println("Throwing LoginException(" + msg + ")");
throw new LoginException(msg);
}
private void throwFailedLoginException(String msg) throws FailedLoginException
{
System.out.println("Throwing FailedLoginException(" + msg + ")");
throw new FailedLoginException(msg);
}
private Callback[] getCallbacks() throws LoginException
{
if (callbackHandler == null) {
throwLoginException("No CallbackHandler Specified");
}
if (database == null) {
throwLoginException("database not specified");
}
Callback[] callbacks;
if (isIdentityAssertion) {
callbacks = new Callback[1];
} else {
callbacks = new Callback[2];
callbacks[1] = new PasswordCallback("password: ",false);
}
callbacks[0] = new NameCallback("username: ");
try {
callbackHandler.handle(callbacks);
} catch (IOException e) {
throw new LoginException(e.toString());
} catch (UnsupportedCallbackException e) {
throwLoginException(e.toString() + " " + e.getCallback().toString());
}
return callbacks;
}
private String getUserName(Callback[] callbacks) throws LoginException
{
String userName = ((NameCallback)callbacks[0]).getName();
if (userName == null) {
throwLoginException("Username not supplied.");
}
System.out.println("\tuserName\t= " + userName);
return userName;
}
private void addGroupsForSubject(String userName)
{
for (Enumeration e = database.getUserGroups(userName);
e.hasMoreElements();) {
String groupName = (String)e.nextElement();
System.out.println("\tgroupName\t= " + groupName);
principalsForSubject.add(new WLSGroupImpl(groupName));
}
}
private String getPasswordHave(String userName, Callback[] callbacks) throws
LoginException
{
PasswordCallback passwordCallback = (PasswordCallback)callbacks[1];
char[] password = passwordCallback.getPassword();
passwordCallback.clearPassword();
if (password == null || password.length < 1) {
throwLoginException("Authentication Failed: User " + userName + ".
Password not supplied");
}
String passwd = new String(password);
System.out.println("\tpasswordHave\t= " + passwd);
return passwd;
}
}
Generate an MBean Type Using the WebLogic MBeanMaker
Before you start generating an MBean type for your custom security provider, you should first:
When you understand this information and have made your design decisions, create the MBean type for your custom Authentication provider by following these steps:
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:
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 Authentication provider. Follow the instructions that are appropriate to your situation:
No Optional SSPI MBeans and No Custom Operations
If the MDF for your custom Authentication provider does not implement any optional SSPI MBeans and does not include any custom operations, follow these steps:
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.
Optional SSPI MBeans or Custom Operations
If the MDF for your custom Authentication provider does implement some optional SSPI MBeans or does include custom operations, consider the following:
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.
The MBean implementation file generated by the WebLogic MBeanMaker is named MBeanNameImpl.java. For example, for the MDF named SampleAuthenticator, the MBean implementation file to be edited is named SampleAuthenticatorImpl.java.
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.
The MBean implementation file generated by the WebLogic MBeanMaker is named <MBeanName>Impl.java. For example, for the MDF named SampleAuthenticator, the MBean implementation file to be edited is named SampleAuthenticatorImpl.java.
Accomplishing this task may include, but is not limited to: copying the method implementations from your existing MBean implementation file into the newly-generated MBean implementation file (or, alternatively, adding the new methods from the newly-generated MBean implementation file to your existing MBean implementation file), and verifying that any changes to method signatures are reflected in the version of the MBean implementation file that you are going to use (for methods that exist in both MBean implementation files).
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 SampleAuthenticator MDF through the WebLogic MBeanMaker will yield an MBean interface file called SampleAuthenticatorMBean.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 Authentication provider into an MBean JAR File (MJF). The WebLogic MBeanMaker also automates this process.
To create an MJF for your custom Authentication provider, follow these steps:
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 Authentication provider—that is, it makes the custom Authentication 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 Authentication provider (see Configure the Custom Authentication 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 Authentication Provider Using the Administration Console
Configuring a custom Authentication provider means that you are adding the custom Authentication provider to your security realm, where it can be accessed by applications requiring authentication 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 Authentication providers:
Note: The steps for configuring a custom Authentication provider using the WebLogic Server Administration Console are described in "Configuring a Custom Security Provider" in Managing WebLogic Security.
As part of using a custom Authentication provider, you need to consider how you will configure and manage user lockouts. You have two choices for doing this:
Rely on the Realm-Wide User Lockout Manager
The WebLogic Security Framework provides a realm-wide User Lockout Manager that works directly with the WebLogic Security Framework to manage user lockouts.
Note: Both the realm-wide User Lockout Manager and a WebLogic Server 6.1 PasswordPolicyMBean (at the Realm Adapter level) may be active. For more information, see the WebLogic Server 6.1API Reference Javadoc for the PasswordPolicyMBean interface.
If you decide to rely on the realm-wide User Lockout Manager, then all you must do to make it work with your custom Authentication provider is use the WebLogic Server Administration Console to:
Notes: Changes to the User Lockout Manager do not take effect until you reboot the server. Instructions for using the Administration Console to perform these tasks are described in "Protecting User Accounts" in Managing WebLogic Security.
Implement Your Own User Lockout Manager
If you decide to implement your own User Lockout Manager as part of your custom Authentication provider, then you must: