Save This Page
Home » jboss-5.0.0.CR1-src » org » jboss » security » auth » spi » [javadoc | source]
    1   /*
    2    * JBoss, the OpenSource WebOS
    3    *
    4    * Distributable under LGPL license.
    5    * See terms of license at gnu.org.
    6    */
    7   package org.jboss.security.auth.spi;
    8   
    9   import java.io.IOException;
   10   import java.io.InputStream;
   11   import java.net.URL;
   12   import java.util.ArrayList;
   13   import java.util.Enumeration;
   14   import java.util.Map;
   15   import java.util.Properties;
   16   import java.util.StringTokenizer;
   17   
   18   import java.security.acl.Group;
   19   import javax.security.auth.Subject;
   20   import javax.security.auth.callback.CallbackHandler;
   21   import javax.security.auth.login.LoginException;
   22   
   23   import org.jboss.security.SimpleGroup;
   24   import org.jboss.security.SimplePrincipal;
   25   import org.jboss.security.auth.spi.UsernamePasswordLoginModule;
   26   
   27   /** A simple properties file based login module that consults two Java Properties
   28   formatted text files for username to password("users.properties") and
   29   username to roles("roles.properties") mapping. The names of the properties
   30   files may be overriden by the usersProperties and rolesProperties options.
   31   The properties files are loaded during initialization using the thread context
   32   class loader. This means that these files can be placed into the J2EE
   33   deployment jar or the JBoss config directory.
   34   
   35   The users.properties file uses a format:
   36       username1=password1
   37       username2=password2
   38       ...
   39   
   40   to define all valid usernames and their corresponding passwords.
   41   
   42   The roles.properties file uses a format:
   43       username1=role1,role2,...
   44       username1.RoleGroup1=role3,role4,...
   45       username2=role1,role3,...
   46   
   47   to define the sets of roles for valid usernames. The "username.XXX" form of
   48   property name is used to assign the username roles to a particular named
   49   group of roles where the XXX portion of the property name is the group name.
   50   The "username=..." form is an abbreviation for "username.Roles=...".
   51   The following are therefore equivalent:
   52       jduke=TheDuke,AnimatedCharacter
   53       jduke.Roles=TheDuke,AnimatedCharacter
   54   
   55   @author <a href="edward.kenworthy@crispgroup.co.uk">Edward Kenworthy</a>, 12th Dec 2000
   56   @author Scott.Stark@jboss.org
   57   */
   58   public class UsersRolesLoginModule extends UsernamePasswordLoginModule
   59   {
   60       /** The name of the properties resource containing user/passwords */
   61       private String usersRsrcName = "users.properties";
   62       /** The name of the properties resource containing user/roles */
   63       private String rolesRsrcName = "roles.properties";
   64       /** The users.properties values */
   65       private Properties users;
   66       /** The roles.properties values */
   67       private Properties roles;
   68   
   69       /** Initialize this LoginModule.
   70        *@param options, the login module option map. Supported options include:
   71        *usersProperties: The name of the properties resource containing
   72         user/passwords. The default is "users.properties"
   73        *rolesProperties: The name of the properties resource containing user/roles
   74         The default is "roles.properties".
   75        */
   76       public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
   77       {
   78           super.initialize(subject, callbackHandler, sharedState, options);
   79           try
   80           {
   81               // Check for usersProperties & rolesProperties
   82               String option = (String) options.get("usersProperties");
   83               if( option != null )
   84                  usersRsrcName = option;
   85               option = (String) options.get("rolesProperties");
   86               if( option != null )
   87                  rolesRsrcName = option;
   88               // Load the properties file that contains the list of users and passwords
   89               loadUsers();
   90               loadRoles();
   91           }
   92           catch(Exception e)
   93           {
   94               // Note that although this exception isn't passed on, users or roles will be null
   95               // so that any call to login will throw a LoginException.
   96               super.log.error("Failed to load users/passwords/role files", e);
   97           }
   98       }
   99   
  100       /** Method to authenticate a Subject (phase 1). This validates that the
  101        *users and roles properties files were loaded and then calls
  102        *super.login to perform the validation of the password.
  103        *@exception LoginException, thrown if the users or roles properties files
  104        *were not found or the super.login method fails.
  105        */
  106       public boolean login() throws LoginException
  107       {
  108           if( users == null )
  109               throw new LoginException("Missing users.properties file.");
  110           if( roles == null )
  111               throw new LoginException("Missing roles.properties file.");
  112   
  113           return super.login();
  114       }
  115   
  116       /** Create the set of roles the user belongs to by parsing the roles.properties
  117           data for username=role1,role2,... and username.XXX=role1,role2,...
  118           patterns.
  119       @return Group[] containing the sets of roles 
  120       */
  121       protected Group[] getRoleSets() throws LoginException
  122       {
  123           String targetUser = getUsername();
  124           Enumeration users = roles.propertyNames();
  125           SimpleGroup rolesGroup = new SimpleGroup("Roles");
  126           ArrayList groups = new ArrayList();
  127           groups.add(rolesGroup);
  128           while( users.hasMoreElements() && targetUser != null )
  129           {
  130               String user = (String) users.nextElement();
  131               String value = roles.getProperty(user);
  132               // See if this entry is of the form targetUser[.GroupName]=roles
  133               int index = user.indexOf('.');
  134               boolean isRoleGroup = false;
  135               boolean userMatch = false;
  136               if( index > 0 && targetUser.regionMatches(0, user, 0, index) == true )
  137                   isRoleGroup = true;
  138               else
  139                  userMatch = targetUser.equals(user);
  140   
  141               // Check for username.RoleGroup pattern
  142               if( isRoleGroup == true )
  143               {
  144                   String groupName = user.substring(index+1);
  145                   if( groupName.equals("Roles") )
  146                       parseGroupMembers(rolesGroup, value);
  147                   else
  148                   {
  149                       SimpleGroup group = new SimpleGroup(groupName);
  150                       parseGroupMembers(group, value);
  151                       groups.add(group);
  152                   }
  153               }
  154               else if( userMatch == true )
  155               {
  156                   // Place these roles into the Default "Roles" group
  157                   parseGroupMembers(rolesGroup, value);
  158               }
  159           }
  160           Group[] roleSets = new Group[groups.size()];
  161           groups.toArray(roleSets);
  162           return roleSets;
  163       }
  164       protected String getUsersPassword()
  165       {
  166           String username = getUsername();
  167           String password = null;
  168           if( username != null )
  169               password = users.getProperty(username , null);
  170           return password;
  171       }
  172   
  173   // utility methods
  174       private void parseGroupMembers(Group group, String value)
  175       {
  176           StringTokenizer tokenizer = new StringTokenizer(value, ",");
  177           while( tokenizer.hasMoreTokens() )
  178           {
  179               String token = tokenizer.nextToken();
  180               SimplePrincipal p = new SimplePrincipal(token);
  181               group.addMember(p);
  182           }
  183       }
  184   
  185       private void loadUsers() throws IOException
  186       {
  187           users = loadProperties(usersRsrcName);
  188       }
  189   
  190       private void loadRoles() throws IOException
  191       {
  192           roles = loadProperties(rolesRsrcName);
  193       }
  194   
  195       /**
  196       * Loads the given properties file and returns a Properties object containing the
  197       * key,value pairs in that file.
  198       * The properties files should be in the class path.
  199       */
  200       private Properties loadProperties(String propertiesName) throws IOException
  201       {
  202           Properties bundle = null;
  203           ClassLoader loader = Thread.currentThread().getContextClassLoader();
  204           URL url = loader.getResource(propertiesName);
  205           if( url == null )
  206               throw new IOException("Properties file " + propertiesName + " not found");
  207           super.log.trace("Properties file="+url);
  208           InputStream is = url.openStream();
  209           if( is != null )
  210           {
  211               bundle = new Properties();
  212               bundle.load(is);
  213           }
  214           else
  215           {
  216               throw new IOException("Properties file " + propertiesName + " not avilable");
  217           }
  218           return bundle;
  219       }
  220   }

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