Developing JAAS custom login modules for database authentication

You can develop a Java™ Authentication and Authorization Service (JAAS) custom login module for adding a user name and password to authenticate to a database.

About this task

You can develop a JAAS custom login module that can be invoked when a database connection that requires authentication is created. The JAAS custom login module is responsible of creating a password credential that contains the user name, password, and managed connection factory. The login module must add the password credential to the subject's private credentials set to be used to authenticate to the database.

Procedure

  1. Create a class that implements the javax.security.auth.spi.LoginModule interface.
  2. Save the necessary fields in the initialize method. For example:
    
    /** {@inheritDoc} */
    @SuppressWarnings("unchecked")
    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
      this.callbackHandler = callbackHandler;
      this.subject = subject;
      this.sharedState = (Map<String, Object>) sharedState;
      this.options = options;
    }
  3. Handle the WSManagedConnectionFactoryCallback and WSMappingPropertiesCallback callbacks in the login method. For example:
    
    /** {@inheritDoc} */
    @Override
    public boolean login() throws LoginException {
      ...
      Callback callbacks[] = new Callback[2];
      callbacks[0] = new WSManagedConnectionFactoryCallback("Target ManagedConnectionFactory: ");
      callbacks[1] = new WSMappingPropertiesCallback("Mapping Properties (HashMap): ");
      callbackHandler.handle(callbacks);
  4. Obtain the managed connection factory and properties in the login method. For example:
    
    // The method getManagedConnectionFactory must be used as shown for compatibility with WebSphere traditional
    ManagedConnectionFactory managedConnectionFactory = ((WSManagedConnectionFactoryCallback) callbacks[0]).getManagedConnectionFacotry();
    Map properties = ((WSMappingPropertiesCallback) callbacks[1]).getProperties();
  5. Obtain the user name and password based on the authentication data alias or some other criteria. For example:
    
    String alias = (String) properties.get(com.ibm.wsspi.security.auth.callback.Constants.MAPPING_ALIAS);
    String user = getUser(alias); // Implementation specific
    char[] password = getPassword(alias); // Implementation specific
  6. Create a javax.resources.spi.PasswordCredential object with the user name and password and set the managed connection factory. For example:
    
    javax.resource.spi.security.PasswordCredential passwordCredential = new PasswordCredential(user, password);
    passwordCredential.setManagedConnectionFactory(managedConnectionFactory);
  7. Add the password credential to the subject in the commit method. For example:
    
    /** {@inheritDoc} */
    @Override
    public boolean commit() throws LoginException {
      // Verify that the login was successful before adding the PasswordCredential to the subject.
      subject.getPrivateCredentials().add(passwordCredential);
      return true;
    }