Skip navigation.
Downloads | Product Documentation | Support

Developing Security Providers

# Code Examples for Developing Security Providers

This section includes the following security provider code examples:

- Example: Creating the Runtime Classes for the Sample Authentication Provider
- Example: Creating the Runtime Class for the Sample Identity Assertion Provider
- Example: Creating the Runtime Class for the Sample Authorization Provider
- Example: Creating the Runtime Class for the Sample Role Mapping Provider
- Example: Creating the Runtime Class for the Sample Auditing Provider
- Example: Implementation of the AuditRoleEvent Interface
- Example: Obtaining and Using the Auditor Service to Write Role Audit Events

# Example: Creating the Runtime Classes for the Sample Authentication Provider

Listing 6-1 shows the `SampleAuthenticationProviderImpl.java` class, which is one of two runtime classes for the sample Authentication provider. This runtime class includes implementations for:

- The three methods inherited from the `SecurityProvider` interface: `initialize`, `getDescription` and `shutdown`
- The four methods in the `AuthenticationProvider` SSPI: the `getLoginModuleConfiguration`, `getAssertionModuleConfiguration`, `getPrincipalValidator`, and `getIdentityAsserter` methods.

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

Listing 6-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 6-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 Implementing the JAAS LoginModule Interface), and therefore includes implementations for its `initialize`, `login`, `commit`, `abort`, and `logout` methods.

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

Listing 6-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;
>        }

>     }

# Example: Creating the Runtime Class for the Sample Identity Assertion Provider

Listing 6-3 shows the `SampleIdentityAsserterProviderImpl.java` class, which is the runtime class for the sample Identity Assertion provider. This runtime class includes implementations for:

- The three methods inherited from the `SecurityProvider` interface: `initialize`, `getDescription`, and `shutdown`
- The four methods in the `AuthenticationProvider` SSPI: the `getLoginModuleConfiguration`, `getAssertionModuleConfiguration`, `getPrincipalValidator`, and `getIdentityAsserter` methods
- The method in the `IdentityAsserter` SSPI: the `assertIdentity` method.

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

Listing 6-3 SampleIdentityAsserterProviderImpl.java

>     package examples.security.providers.identityassertion;

>     import javax.security.auth.callback.CallbackHandler;
>     import javax.security.auth.login.AppConfigurationEntry;
>     import weblogic.management.security.ProviderMBean;
>     import weblogic.security.spi.AuthenticationProvider;
>     import weblogic.security.spi.IdentityAsserter;
>     import weblogic.security.spi.IdentityAssertionException;
>     import weblogic.security.spi.PrincipalValidator;
>     import weblogic.security.spi.SecurityServices;

>     public final class SampleIdentityAsserterProviderImpl implements AuthenticationProvider, IdentityAsserter
>     {
>        final static private String TOKEN_TYPE   = "SamplePerimeterAtnToken";
>        final static private String TOKEN_PREFIX = "username=";

>        private String description;

>        public void initialize(ProviderMBean mbean, SecurityServices services)
>        {
>           System.out.println("SampleIdentityAsserterProviderImpl.initialize");
>           SampleIdentityAsserterMBean myMBean = (SampleIdentityAsserterMBean)mbean;
>           description = myMBean.getDescription() + "\n" + myMBean.getVersion();
>        }

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

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

>        public AppConfigurationEntry getLoginModuleConfiguration()
>        {
>           return null;
>        }

>        public AppConfigurationEntry getAssertionModuleConfiguration()
>        {
>           return null;
>        }

>        public PrincipalValidator getPrincipalValidator()
>        {
>           return null;
>        }

>        public IdentityAsserter getIdentityAsserter()
>        {
>           return this;
>        }

>        public CallbackHandler assertIdentity(String type, Object token) throws
>        IdentityAssertionException
>        {
>           System.out.println("SampleIdentityAsserterProviderImpl.assertIdentity");
>           System.out.println("\tType\t\t= "  + type);
>           System.out.println("\tToken\t\t= " + token);

>           if (!(TOKEN_TYPE.equals(type))) {
>              String error = "SampleIdentityAsserter received unknown token type \""
>                 + type + "\"." + " Expected " + TOKEN_TYPE;
>              System.out.println("\tError: " + error);
>              throw new IdentityAssertionException(error);
>           }

>           if (!(token instanceof byte[])) {
>              String error = "SampleIdentityAsserter received unknown token class \""
>                 + token.getClass() + "\"." + " Expected a byte[].";
>              System.out.println("\tError: " + error);
>              throw new IdentityAssertionException(error);
>           }

>           byte[] tokenBytes = (byte[])token;
>           if (tokenBytes == null || tokenBytes.length < 1) {
>              String error = "SampleIdentityAsserter received empty token byte array";
>              System.out.println("\tError: " + error);
>              throw new IdentityAssertionException(error);
>           }

>           String tokenStr = new String(tokenBytes);

>           if (!(tokenStr.startsWith(TOKEN_PREFIX))) {
>              String error = "SampleIdentityAsserter received unknown token string \""
>                 + type + "\"." + " Expected " + TOKEN_PREFIX + "username";
>              System.out.println("\tError: " + error);
>              throw new IdentityAssertionException(error);
>           }

>           String userName = tokenStr.substring(TOKEN_PREFIX.length());
>           System.out.println("\tuserName\t= " + userName);
>           return new SampleCallbackHandlerImpl(userName);
>        }

>     }

Listing 6-4 shows the sample `CallbackHandler` implementation that is used along with the `SampleIdentityAsserterProviderImpl.java` runtime class. This `CallbackHandler` implementation is used to send the username back to an Authentication provider's LoginModule.

Listing 6-4 SampleCallbackHandlerImpl.java

>     package examples.security.providers.identityassertion;

>     import javax.security.auth.callback.Callback;
>     import javax.security.auth.callback.NameCallback;
>     import javax.security.auth.callback.CallbackHandler;
>     import javax.security.auth.callback.UnsupportedCallbackException;

>     /*package*/ class SampleCallbackHandler implements CallbackHandler
>     {
>        private String userName;

>        /*package*/ SampleCallbackHandlerImpl(String user)
>        {
>           userName = user;
>        }

>        public void handle(Callback[] callbacks) throws UnsupportedCallbackException
>        {
>           for (int i = 0; i < callbacks.length; i++) {

>                 Callback callback = callbacks[i];

>                 if (!(callback instanceof NameCallback)) {
>                    throw new UnsupportedCallbackException(callback, "Unrecognized
>                       Callback");
>                 }

>                 NameCallback nameCallback = (NameCallback)callback;
>                 nameCallback.setName(userName);
>           }
>        }
>     }

# Example: Creating the Runtime Class for the Sample Authorization Provider

Listing 6-5 shows the `SampleAuthorizationProviderImpl.java` class, which is the runtime class for the sample Authorization provider. This runtime class includes implementations for:

- The three methods inherited from the `SecurityProvider` interface: `initialize`, `getDescription` and `shutdown`
- The method inherited from the `AuthorizationProvider` SSPI: the `getAccessDecision` method.
- The two methods in the `AccessDecision` SSPI: the `isAccessAllowed` and `isProtectedResource` methods.

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

Listing 6-5 SampleAuthorizationProviderImpl.java

>     package examples.security.providers.authorization;

>     import java.security.Principal;
>     import java.util.Enumeration;
>     import java.util.Iterator;
>     import java.util.Map;
>     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.AccessDecision;
>     import weblogic.security.spi.DeployableAuthorizationProvider;
>     import weblogic.security.spi.Direction;
>     import weblogic.security.spi.InvalidPrincipalException;
>     import weblogic.security.spi.Resource;
>     import weblogic.security.spi.ResourceCreationException;
>     import weblogic.security.spi.ResourceRemovalException;
>     import weblogic.security.spi.Result;
>     import weblogic.security.spi.SecurityServices;

>     public final class SampleAuthorizationProviderImpl implements AuthorizationProvider, AccessDecision
>     {
>        private String description;
>        private SampleAuthorizerDatabase database;

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

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

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

>        public AccessDecision getAccessDecision()
>        {
>           return this;
>        }

>        public Result isAccessAllowed(Subject subject, Map roles, Resource resource,
>        ContextHandler handler, Direction direction) throws InvalidPrincipalException
>        {
>           System.out.println("SampleAuthorizationProviderImpl.isAccessAllowed");
>           System.out.println("\tsubject\t= " + subject);
>           System.out.println("\troles\t= " + roles);
>           System.out.println("\tresource\t= " + resource);
>           System.out.println("\tdirection\t= " + direction);

>           Set principals = subject.getPrincipals();

>           for (Resource res = resource; res != null; res = res.getParentResource()) {
>              if (database.policyExists(res)) {
>                 return isAccessAllowed(res, principals, roles);
>              }
>           }
>           return Result.ABSTAIN;
>        }

>        public boolean isProtectedResource(Subject subject, Resource resource) throws
>        InvalidPrincipalException
>        {
>           System.out.println("SampleAuthorizationProviderImpl.
>             isProtectedResource");
>           System.out.println("\tsubject\t= " + subject);
>           System.out.println("\tresource\t= " + resource);

>           for (Resource res = resource; res != null; res = res.getParentResource()) {
>              if (database.policyExists(res)) {
>                 return true;
>              }
>           }
>           return false;
>        }

>        private Result isAccessAllowed(Resource resource, Set principals, Map roles)
>        {
>           for (Enumeration e = database.getPolicy(resource); e.hasMoreElements();)
>           {
>            String principalOrRoleNameAllowed = (String)e.nextElement();
>            if (WLSPrincipals.getEveryoneGroupname().
>              equals(principalOrRoleNameAllowed) ||
>              (WLSPrincipals.getUsersGroupname().equals(principalOrRoleNameAllowed)
>              && !principals.isEmpty()) || principalsOrRolesContain(principals,
>              roles, principalOrRoleNameAllowed))
>              {
>                 return Result.PERMIT;
>              }
>           }
>           return Result.DENY;
>        }
>     }

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

Listing 6-6 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`.
- The method inherited from the `RoleProvider` SSPI: the `getRoleMapper` method.
- The method in the `RoleMapper` SSPI: the `getRoles` method.

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

Listing 6-6 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 RoleProvider, 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;
>        }

>        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 6-7 shows the sample `SecurityRole` implementation that is used along with the `SampleRoleMapperProviderImpl.java` runtime class.

Listing 6-7 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; }
>     }

# Example: Creating the Runtime Class for the Sample Auditing Provider

Listing 6-8 shows the `SampleAuditProviderImpl.java` class, which is the runtime class for the sample Auditing provider. This runtime class includes implementations for:

- The three methods inherited from the `SecurityProvider` interface: `initialize`, `getDescription` and `shutdown.`
- The method inherited from the `AuditProvider` SSPI: the `getAuditChannel` method.
- The method in the Audit Channel SSPI: the `writeEvent` method.

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

Listing 6-8 SampleAuditProviderImpl.java

>     package examples.security.providers.audit;

>     import java.io.File;
>     import java.io.FileOutputStream;
>     import java.io.IOException;
>     import java.io.PrintStream;
>     import weblogic.management.security.ProviderMBean;
>     import weblogic.security.spi.AuditChannel;
>     import weblogic.security.spi.AuditEvent;
>     import weblogic.security.spi.AuditProvider;
>     import weblogic.security.spi.SecurityServices;

>     public final class SampleAuditProviderImpl implements AuditChannel, AuditProvider
>     {
>        private String description;
>        private PrintStream log;

>        public void initialize(ProviderMBean mbean, SecurityServices services)
>        {
>           System.out.println("SampleAuditProviderImpl.initialize");

>           description = mbean.getDescription() + "\n" + mbean.getVersion();

>           SampleAuditorMBean myMBean = (SampleAuditorMBean)mbean;
>           File file = new File(myMBean.getLogFileName());
>           System.out.println("\tlogging to " + file.getAbsolutePath());

>           try {
>              log = new PrintStream(new FileOutputStream(file), true);
>           } catch (IOException e) {
>              throw new RuntimeException(e.toString());
>           }
>        }

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

>        public void shutdown()
>        {
>           System.out.println("SampleAuditProviderImpl.shutdown");
>           log.close();
>        }

>        public AuditChannel getAuditChannel()
>        {
>           return this;
>        }

>        public void writeEvent(AuditEvent event)
>        {
>           // Write the event out to the sample Auditing provider's log file using
>           // the event's "toString" method.
>           log.println(event);
>        }
>     }

# Example: Implementation of the AuditRoleEvent Interface

Listing 6-9 shows the `MyAuditRoleEventImpl.java` class, which is a sample implementation of an Audit Event convenience interface (in this case, the `AuditRoleEvent` convenience interface). This class includes implementations for:

- The four methods inherited from the `AuditEvent` SSPI: `getEventType`, `getFailureException`, `getSeverity` and `toString`
- One additional method: `getContext`, which returns additional contextual information via the ContextHandler.

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

Listing 6-9 MyAuditRoleEventImpl.java

>     package mypackage;

>     import javax.security.auth.Subject;
>     import weblogic.security.SubjectUtils;
>     import weblogic.security.service.ContextHandler;
>     import weblogic.security.spi.AuditRoleEvent;
>     import weblogic.security.spi.AuditSeverity;
>     import weblogic.security.spi.Resource;

>     /*package*/ class MyAuditRoleEventImpl implements AuditRoleEvent
>     {
>        private Subject subject;
>        private Resource resource;
>        private ContextHandler context;
>        private String details;
>        private Exception failureException;

>        /*package*/ MyAuditRoleEventImpl(Subject subject, Resource resource,
>           ContextHandler context, String details, Exception
>           failureException) {

>              this.subject = subject;
>              this.resource = resource;
>              this.context = context;
>              this.details = details;
>              this.failureException = failureException;
>        }

>        public Exception getFailureException()
>        {
>           return failureException;
>        }

>        public AuditSeverity getSeverity()
>        {
>           return (failureException == null) ? AuditSeverity.SUCCESS :
>              AuditSeverity.FAILURE;
>        }

>        public String getEventType()
>        {
>           return "MyAuditRoleEventType";
>        }

>        public ContextHandler getContext()
>        {
>           return context;
>        }

>        public String toString()
>        {
>           StringBuffer buf = new StringBuffer();
>           buf.append("EventType:" + getEventType() + "\n");
>           buf.append("\tSeverity: " +
>              getSeverity().getSeverityString());
>           buf.append("\tSubject: " +
>              SubjectUtils.displaySubject(getSubject());
>           buf.append("\tResource: " + resource.toString());
>           buf.append("\tDetails: " + details);

>           if (getFailureException() != null) {
>              buf.append("\n\tFailureException:" +
>                 getFailureException());
>           }

>           return buf.toString();
>        }

>     }

# Example: Obtaining and Using the Auditor Service to Write Role Audit Events

Listing 6-10 illustrates how a custom Role Mapping provider's runtime class (called `MyRoleMapperProviderImpl.java`) would obtain the Auditor Service and use it to write out audit events.

Note: The `MyRoleMapperProviderImpl.java` class relies on the `MyAuditRoleEventImpl.java` class from Listing 6-10.

Listing 6-10 MyRoleMapperProviderImpl.java

>     package mypackage;

>     import javax.security.auth.Subject;
>     import weblogic.management.security.ProviderMBean;
>     import weblogic.security.SubjectUtils;
>     import weblogic.security.service.ContextHandler;
>     import weblogic.security.spi.AuditorService;
>     import weblogic.security.spi.RoleMapper;
>     import weblogic.security.spi.RoleProvider;
>     import weblogic.security.spi.Resource;
>     import weblogic.security.spi.SecurityServices;

>     public final class MyRoleMapperProviderImpl implements RoleProvider, RoleMapper
>     {

>        private AuditorService auditor;

>        public void initialize(ProviderMBean mbean, SecurityServices
>           services)
>        {
>           auditor = services.getAuditorService();
>           ...
>        }

>        public Map getRoles(Subject subject, Resource resource,
>           ContextHandler handler)
>        {
>           ...
>           if (auditor != null)
>           {
>              auditor.providerAuditWriteEvent(
>                 new MyRoleEventImpl(subject, resource, context,
>                 "why logging this event",
>                 null);                // no exception occurred
>           }
>           ...
>        }

>     }