View Javadoc

1   // ========================================================================
2   // $Id: PropertyFileLoginModule.java 478 2006-04-23 22:00:17Z gregw $
3   // Copyright 1999-2004 Mort Bay Consulting Pty. Ltd.
4   // ------------------------------------------------------------------------
5   // Licensed under the Apache License, Version 2.0 (the "License");
6   // you may not use this file except in compliance with the License.
7   // You may obtain a copy of the License at 
8   // http://www.apache.org/licenses/LICENSE-2.0
9   // Unless required by applicable law or agreed to in writing, software
10  // distributed under the License is distributed on an "AS IS" BASIS,
11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  // See the License for the specific language governing permissions and
13  // limitations under the License.
14  // ========================================================================
15  
16  package org.mortbay.jetty.plus.jaas.spi;
17  
18  import java.io.File;
19  import java.io.FileInputStream;
20  import java.util.ArrayList;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.Map;
24  import java.util.Properties;
25  import java.util.StringTokenizer;
26  
27  import javax.security.auth.Subject;
28  import javax.security.auth.callback.CallbackHandler;
29  
30  import org.mortbay.jetty.security.Credential;
31  import org.mortbay.log.Log;
32  
33  /**
34   * PropertyFileLoginModule
35   *
36   *
37   */
38  public class PropertyFileLoginModule extends AbstractLoginModule
39  {
40      public static final String DEFAULT_FILENAME = "realm.properties";
41      public static final Map fileMap = new HashMap(); 
42      
43      private String propertyFileName;
44      
45      
46  
47      /** 
48       * Read contents of the configured property file.
49       * 
50       * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
51       * @param subject
52       * @param callbackHandler
53       * @param sharedState
54       * @param options
55       */
56      public void initialize(Subject subject, CallbackHandler callbackHandler,
57              Map sharedState, Map options)
58      {
59          super.initialize(subject, callbackHandler, sharedState, options);
60          loadProperties((String)options.get("file"));
61      }
62      
63    
64      
65      public void loadProperties (String filename)
66      {
67          File propsFile;
68          
69          if (filename == null)
70          {
71              propsFile = new File(System.getProperty("user.dir"), DEFAULT_FILENAME);
72              //look for a file called realm.properties in the current directory
73              //if that fails, look for a file called realm.properties in $jetty.home/etc
74              if (!propsFile.exists())
75                  propsFile = new File(System.getProperty("jetty.home"), DEFAULT_FILENAME);
76          }
77          else
78          {
79              propsFile = new File(filename);
80          }
81          
82          //give up, can't find a property file to load
83          if (!propsFile.exists())
84          {
85              Log.warn("No property file found");
86              throw new IllegalStateException ("No property file specified in login module configuration file");
87          }
88              
89          
90       
91          try
92          {
93              this.propertyFileName = propsFile.getCanonicalPath();
94              if (fileMap.get(propertyFileName) != null)
95              {
96                  if (Log.isDebugEnabled()) {Log.debug("Properties file "+propertyFileName+" already in cache, skipping load");}
97                  return;
98              }
99              
100             Map userInfoMap = new HashMap();
101             Properties props = new Properties();
102             props.load(new FileInputStream(propsFile));
103             Iterator iter = props.entrySet().iterator();
104             while(iter.hasNext())
105             {
106                 
107                 Map.Entry entry = (Map.Entry)iter.next();
108                 String username=entry.getKey().toString().trim();
109                 String credentials=entry.getValue().toString().trim();
110                 String roles=null;
111                 int c=credentials.indexOf(',');
112                 if (c>0)
113                 {
114                     roles=credentials.substring(c+1).trim();
115                     credentials=credentials.substring(0,c).trim();
116                 }
117 
118                 if (username!=null && username.length()>0 &&
119                     credentials!=null && credentials.length()>0)
120                 {
121                     ArrayList roleList = new ArrayList();
122                     if(roles!=null && roles.length()>0)
123                     {
124                         StringTokenizer tok = new StringTokenizer(roles,", ");
125                         
126                         while (tok.hasMoreTokens())
127                             roleList.add(tok.nextToken());
128                     }
129                     
130                     userInfoMap.put(username, (new UserInfo(username, Credential.getCredential(credentials.toString()), roleList)));
131                 }
132             }
133             
134             fileMap.put(propertyFileName, userInfoMap);
135         }
136         catch (Exception e)
137         {
138             Log.warn("Error loading properties from file", e);
139             throw new RuntimeException(e);
140         }
141     }
142 
143     /** 
144      * Don't implement this as we want to pre-fetch all of the
145      * users.
146      * @see org.mortbay.jetty.plus.jaas.spi.AbstractLoginModule#lazyLoadUser(java.lang.String)
147      * @param username
148      * @throws Exception
149      */
150     public UserInfo getUserInfo (String username) throws Exception
151     {
152         Map userInfoMap = (Map)fileMap.get(propertyFileName);
153         if (userInfoMap == null)
154             return null;
155         return (UserInfo)userInfoMap.get(username);
156     }
157 
158 }