Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » security » [javadoc | source]
    1   /*
    2    * JBoss, the OpenSource WebOS
    3    *
    4    * Distributable under LGPL license.
    5    * See terms of license at gnu.org.
    6    */
    7   
    8   package org.jboss.security;
    9   
   10   
   11   import java.util.Map;
   12   import java.security.Principal;
   13   import javax.security.auth.Subject;
   14   import javax.security.auth.callback.Callback;
   15   import javax.security.auth.callback.CallbackHandler;
   16   import javax.security.auth.callback.NameCallback;
   17   import javax.security.auth.callback.PasswordCallback;
   18   import javax.security.auth.callback.UnsupportedCallbackException;
   19   import javax.security.auth.login.LoginException;
   20   import javax.security.auth.spi.LoginModule;
   21   
   22   /** A simple implementation of LoginModule for use by JBoss clients for
   23    the establishment of the caller identity and credentials. This simply sets
   24    the SecurityAssociation principal to the value of the NameCallback
   25    filled in by the CallbackHandler, and the SecurityAssociation credential
   26    to the value of the PasswordCallback filled in by the CallbackHandler.
   27    
   28    It has the following options:
   29    <ul>
   30    <li>multi-threaded=[true|false]
   31    When the multi-threaded option is set to true, the SecurityAssociation.setServer()
   32    so that each login thread has its own principal and credential storage.
   33    <li>password-stacking=tryFirstPass|useFirstPass
   34    When password-stacking option is set, this module first looks for a shared
   35    username and password using "javax.security.auth.login.name" and
   36    "javax.security.auth.login.password" respectively. This allows a module configured
   37    prior to this one to establish a valid username and password that should be passed
   38    to JBoss.
   39    </ul>
   40    
   41    @author <a href="mailto:on@ibis.odessa.ua">Oleg Nitz</a>
   42    @author Scott.Stark@jboss.org
   43    */
   44   public class ClientLoginModule implements LoginModule
   45   {
   46      private Subject subject;
   47      private CallbackHandler callbackHandler;
   48      /** Shared state between login modules */
   49      private Map sharedState;
   50      /** Flag indicating if the shared password should be used */
   51      private boolean useFirstPass;
   52      
   53      /**
   54       * Initialize this LoginModule.
   55       */
   56      public void initialize(Subject subject, CallbackHandler callbackHandler,
   57         Map sharedState, Map options)
   58      {
   59         this.subject = subject;
   60         this.callbackHandler = callbackHandler;
   61         this.sharedState = sharedState;
   62         // Check for multi-threaded option
   63         String mt = (String) options.get("multi-threaded");
   64         if( mt != null && Boolean.valueOf(mt).booleanValue() == true )
   65         {   /* Turn on the server mode which uses thread local storage for
   66                   the principal information.
   67            */
   68            SecurityAssociation.setServer();
   69         }
   70         
   71           /* Check for password sharing options. Any non-null value for
   72               password_stacking sets useFirstPass as this module has no way to
   73               validate any shared password.
   74            */
   75         String passwordStacking = (String) options.get("password-stacking");
   76         useFirstPass = passwordStacking != null;
   77      }
   78   
   79      /**
   80       * Method to authenticate a Subject (phase 1).
   81       */
   82      public boolean login() throws LoginException
   83      {
   84         // If useFirstPass is true, look for the shared password
   85         if( useFirstPass == true )
   86         {
   87            try
   88            {
   89               Object user = sharedState.get("javax.security.auth.login.name");
   90               Principal principal;
   91               if( (user instanceof Principal) == false )
   92               {
   93                  String username = user != null ? user.toString() : "";
   94                  principal = new SimplePrincipal(username);
   95               }
   96               else
   97               {
   98                  principal = (Principal) user;
   99               }
  100               Object credential = sharedState.get("javax.security.auth.login.password");
  101               SecurityAssociation.setPrincipal(principal);
  102               SecurityAssociation.setCredential(credential);
  103               SecurityAssociation.setSubject(subject);
  104               return true;
  105            }
  106            catch(Exception e)
  107            {   // Dump the exception and continue
  108               e.printStackTrace();
  109            }
  110         }
  111   
  112        /* There is no password sharing or we are the first login module. Get
  113            the username and password from the callback hander.
  114         */
  115         if (callbackHandler == null)
  116            throw new LoginException("Error: no CallbackHandler available " +
  117               "to garner authentication information from the user");
  118         
  119         PasswordCallback pc = new PasswordCallback("Password: ", false);
  120         NameCallback nc = new NameCallback("User name: ", "guest");
  121         Callback[] callbacks = {nc, pc};
  122         try
  123         {
  124            String username;
  125            char[] password = null;
  126            char[] tmpPassword;
  127            
  128            callbackHandler.handle(callbacks);
  129            username = nc.getName();
  130            SecurityAssociation.setPrincipal(new SimplePrincipal(username));
  131            tmpPassword = pc.getPassword();
  132            if (tmpPassword != null)
  133            {
  134               password = new char[tmpPassword.length];
  135               System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
  136               pc.clearPassword();
  137            }
  138            SecurityAssociation.setCredential(password);
  139            SecurityAssociation.setSubject(subject);
  140         }
  141         catch (java.io.IOException ioe)
  142         {
  143            throw new LoginException(ioe.toString());
  144         }
  145         catch (UnsupportedCallbackException uce)
  146         {
  147            throw new LoginException("Error: " + uce.getCallback().toString() +
  148            " not available to garner authentication information " +
  149            "from the user");
  150         }
  151         return true;
  152      }
  153   
  154      /**
  155       * Method to commit the authentication process (phase 2).
  156       */
  157      public boolean commit() throws LoginException
  158      {
  159         return true;
  160      }
  161      
  162      /**
  163       * Method to abort the authentication process (phase 2).
  164       */
  165      public boolean abort() throws LoginException
  166      {
  167         SecurityAssociation.clear();
  168         return true;
  169      }
  170      
  171      public boolean logout() throws LoginException
  172      {
  173         SecurityAssociation.clear();
  174         return true;
  175      }
  176   }

Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » security » [javadoc | source]