certloginmodule.java

来自「weblogic应用全实例」· Java 代码 · 共 391 行

JAVA
391
字号
/**
 * CertLoginModule.java
 *
 * This LoginModule authenticates with certificate based mutual authentication.
 * 
 * @author Copyright (c) 2001 by BEA. All Rights Reserved.
 */

package examples.security.jaas;

import java.util.Map;
import java.util.Hashtable;
import java.util.Vector;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.RemoteException;
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.TextInputCallback;
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.security.auth.Authenticate;
import weblogic.security.PEMInputStream;
import weblogic.jndi.Environment;

/**
 * Sample login module for certificate based mutual authentication.
 */
public class CertLoginModule implements LoginModule 
{
  private Subject subject = null;
  private CallbackHandler callbackHandler = null;
  private Map sharedState = null;
  private Map options = null;
  private boolean debug = true;
  private String url = null;

  // Authentication status
  private boolean succeeded = false;
  private boolean commitSucceeded = false;

  /**
   * Initialize
   */
  public void initialize(Subject subject,
                         CallbackHandler callbackHandler,
                         Map sharedState,
                         Map options) 
  {
    this.subject = subject;
    this.callbackHandler = callbackHandler;
    this.sharedState = sharedState;
    this.options = options;

    // Check options for login module debug enabled
    if(options != null)
    {
      Hashtable opt = (Hashtable) options;
      Object val = opt.get("debug");
      if((val != null) && ((String) val).equalsIgnoreCase("true"))
      {
        debug = true;
        System.out.println("CertLoginModule.initialize(), debug enabled");
      }
    }

    try
    {
      // Retrieve WLS server URL string
      url = System.getProperty("weblogic.security.jaas.ServerURL");
      if(debug)
        System.out.println("CertLoginModule.initialize(), URL " + url);
    }
    catch(NullPointerException npe)
    {
      System.err.println("Error: ServerURL Not Specified");
    }
    catch(IllegalArgumentException iae)
    {
      System.err.println("Error: ServerURL Not Specified");
    }
    catch(SecurityException se)
    {
      System.err.println("Error: Security Exception on accessing ServerURL Specification");
    }
  }

  /**
   * Authenticate the user by username, certificate, and cert password
   *
   * @return true in all cases 
   *
   * @exception FailedLoginException if the authentication fails. 
   *
   * @exception LoginException if this LoginModule
   *		is unable to perform the authentication.
   */
  public boolean login() throws LoginException 
  {
    String username = null;
    String certFile = null;
    String certKeyFile = null;
    String CAcertFile = null;
    String certKeyPassword = null;

    // Verify that the client supplied a callback handler
    if(callbackHandler == null)
    {
      if(debug)
        System.out.println("CertLoginModule.login(), no callback handler specifed");
      throw new LoginException("No CallbackHandler Specified");
    }

    // Populate callback list
    Callback[] callbacks = new Callback[4];
    callbacks[0] = new TextInputCallback("Certificate File: ");
    callbacks[1] = new TextInputCallback("Certificate Key File: ");
    callbacks[2] = new TextInputCallback("Root CA Certificate File: ");
    callbacks[3] = new PasswordCallback("Certificate Key Password [Optional]: ", true);
    try
    {
      // Prompt for username and password
      callbackHandler.handle(callbacks);
      if(debug)
        System.out.println("CertLoginModule.login(), callbacks complete, extracting parameters");

      // Retrieve certificate file name
      certFile = ((TextInputCallback) callbacks[0]).getText();
      if(debug)
        System.out.println("  Cert filename: " + certFile);

      // Retrieve certificate key file name
      certKeyFile = ((TextInputCallback) callbacks[1]).getText();
      if(debug)
        System.out.println("  Cert key filename: " + certKeyFile);

      // Retrieve root ca certificate file name
      CAcertFile = ((TextInputCallback) callbacks[2]).getText();
      if(debug)
        System.out.println("  Cert key filename: " + certKeyFile);

      // Retrieve cert key password, converting from char[] to String
      char[] charPassword = ((PasswordCallback) callbacks[3]).getPassword();
      if((charPassword != null) && (charPassword.length != 0))
      {
        certKeyPassword = new String(charPassword);
        if(debug)
          System.out.println("  Cert password: " + certKeyPassword);
      }
      else
      {
        if(debug)
          System.out.println("  Cert password: ** None Specified **");
      }
    }
    catch(IOException ioe)
    {
      throw new LoginException(ioe.toString());
    }
    catch(UnsupportedCallbackException uce)
    {
      throw new LoginException("Error: Callback " + uce.getCallback().toString() + " Not Available");
    }

    /**
     * Populate weblogic environment and authenticate
     */
    Environment env = new Environment();

    // Set server url
    env.setProviderUrl(url);

    // Insert "bogus" username
    //
    // Note: This is needed to fulfill an internal WLS logic inconsistancy, the
    //       value is not used or preserved within WLS
    env.setSecurityPrincipal("bogus");

    // Generate cert input stream array, key followed by cert(s)
    //
    // Note: Files that are in pem format may contain more than
    //       one pem encoded cert. The minimum size for a PEM is 64
    //       (see PEMInputStream)
    Vector tmpStream = new Vector();

    // Add cert key file to collection vector
    try
    {
      InputStream is = new FileInputStream(certKeyFile);
      if(certKeyFile.toLowerCase().endsWith(".pem"))
      {
        while(is.available() > 64)
        {
          // While we still possibly have a cert keep parsing certs from the input stream
          PEMInputStream pis = new PEMInputStream(is);
          tmpStream.addElement(pis);
        }
      }
      else
      {
        // der encoded files can only contain one cert
        tmpStream.addElement(is);
      }
    }
    catch(IOException ioe)
    {
      if(debug)
        System.err.println("CertLoginModule.login(), IO Exception on attempting to read certificate key file [" +
                           certKeyFile + "] , " + ioe.getMessage());
      throw new LoginException(ioe.toString());
    }

    // Add cert(s) to collection vector
    try
    {
      InputStream is = new FileInputStream(certFile);
      if(certFile.toLowerCase().endsWith(".pem"))
      {
        while(is.available() > 64)
        {
          // While we still possibly have a cert keep parsing certs from the input stream
          PEMInputStream pis = new PEMInputStream(is);
          tmpStream.addElement(pis);
        }
      }
      else
      {
        // der encoded files can only contain one cert
        tmpStream.addElement(is);
      }
    }
    catch(IOException ioe)
    {
      if(debug)
        System.err.println("CertLoginModule.login(), IO Exception on attempting to read certificate file [" +
                           certFile + "] , " + ioe.getMessage());
      throw new LoginException(ioe.toString());
    }

    // Add CA cert(s) to collection vector
    try
    {
      InputStream is = new FileInputStream(CAcertFile);
      if(CAcertFile.toLowerCase().endsWith(".pem"))
      {
        while(is.available() > 64)
        {
          // While we still possibly have a cert keep parsing certs from the input stream
          PEMInputStream pis = new PEMInputStream(is);
          tmpStream.addElement(pis);
        }
      }
      else
      {
        // der encoded files can only contain one cert
        tmpStream.addElement(is);
      }
    }
    catch(IOException ioe)
    {
      if(debug)
        System.err.println("CertLoginModule.login(), IO Exception on attempting to read CA certificate file [" +
                           certFile + "] , " + ioe.getMessage());
      throw new LoginException(ioe.toString());
    }

    // Pack cert/key streams and add them to the env instance
    if(debug)
      System.out.println("CertLoginModule.login(), cert/key stream count = " + tmpStream.size());

    InputStream[] streams = new InputStream[tmpStream.size()];
    for(int i = 0; i < tmpStream.size(); i++)
      streams[i] = (InputStream) tmpStream.elementAt(i);
    env.setSSLClientCertificate(streams);

    // Set client cert key password, if provided
    if(certKeyPassword != null)
      env.setSSLClientKeyPassword(certKeyPassword);

    try
    {
      if(debug)
        System.out.println("CertLoginModule.login(), attempting to authenticate");

      // Authenticate user credentials, populating Subject
      Authenticate.authenticate(env, subject);
    }
    catch(RemoteException re)
    {
      if(debug)
        System.err.println("CertLoginModule.login(), RemoteException on authenticate, " + re.getMessage());
      throw new LoginException(re.toString());
    }
    catch(IOException ioe)
    {
      if(debug)
        System.err.println("CertLoginModule.login(), IO Exception on authenticate, " + ioe.getMessage());
      throw new LoginException(ioe.toString());
    }
    catch(LoginException le)
    {
      if(debug)
        System.err.println("CertLoginModule.login(), LoginException on authenticate, " + le.getMessage());
      throw new LoginException(le.toString());
    }

    // Successfully authenticated subject with supplied info
    succeeded = true;
    return succeeded;
  }

  /**
   * This method is called if the LoginContext's overall authentication succeeded
   * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules succeeded).
   *
   * If this LoginModule's own authentication attempted failed, then this method removes
   * any state that was originally saved.
   *
   * @exception LoginException if the commit fails.
   *
   * @return true if this LoginModule's own login and commit
   *		attempts succeeded, or false otherwise.
   */
  public boolean commit() throws LoginException
  {
    if(succeeded)
    {
      commitSucceeded = true;
      return true;
    }
    else
    {
      return false;
    }
  }

  /**
   * This method is called if the LoginContext's
   * overall authentication failed.
   * If this LoginModule's own authentication attempt
   * succeeded (checked by retrieving the private state saved by the
   * login and commit methods),then this method cleans up any state that was originally saved.
   *
   * @exception LoginException if the abort fails.
   *
   * @return false if this LoginModule's own login and/or commit attempts
   *		failed, and true otherwise.
   */
  public boolean abort() throws LoginException
  {
    if(succeeded == false)
    {
      return false;
    }
    else if((succeeded == true) && (commitSucceeded == false))
    {
      // Login succeeded but overall authentication failed
      succeeded = false;
    }
    else
    {
      // Overall authentication succeeded and commit succeeded,
      // but a commit further down the authentication chain failed
      logout();
    }
    return true;
  }

  /**
   * Logout the user.
   *
   * @exception LoginException if the logout fails.
   *
   * @return true in all cases since this LoginModule
   *          should not be ignored.
   */
  public boolean logout() throws LoginException
  {
    succeeded = false;
    commitSucceeded = false;
    return true;
  }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?