View Javadoc

1   // ========================================================================
2   // Copyright (c) 1999-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.plus.jaas.spi;
15  
16  import java.io.File;
17  import java.io.FileInputStream;
18  import java.util.ArrayList;
19  import java.util.HashMap;
20  import java.util.Iterator;
21  import java.util.Map;
22  import java.util.Properties;
23  import java.util.StringTokenizer;
24  
25  import javax.security.auth.Subject;
26  import javax.security.auth.callback.CallbackHandler;
27  
28  import org.eclipse.jetty.http.security.Credential;
29  import org.eclipse.jetty.util.log.Log;
30  
31  /**
32   * PropertyFileLoginModule
33   *
34   *
35   */
36  public class PropertyFileLoginModule extends AbstractLoginModule
37  {
38      public static final String DEFAULT_FILENAME = "realm.properties";
39      public static final Map fileMap = new HashMap(); 
40      
41      private String propertyFileName;
42      
43      
44  
45      /** 
46       * Read contents of the configured property file.
47       * 
48       * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
49       * @param subject
50       * @param callbackHandler
51       * @param sharedState
52       * @param options
53       */
54      public void initialize(Subject subject, CallbackHandler callbackHandler,
55              Map sharedState, Map options)
56      {
57          super.initialize(subject, callbackHandler, sharedState, options);
58          loadProperties((String)options.get("file"));
59      }
60      
61    
62      
63      public void loadProperties (String filename)
64      {
65          File propsFile;
66          
67          if (filename == null)
68          {
69              propsFile = new File(System.getProperty("user.dir"), DEFAULT_FILENAME);
70              //look for a file called realm.properties in the current directory
71              //if that fails, look for a file called realm.properties in $jetty.home/etc
72              if (!propsFile.exists())
73                  propsFile = new File(System.getProperty("jetty.home"), DEFAULT_FILENAME);
74          }
75          else
76          {
77              propsFile = new File(filename);
78          }
79          
80          //give up, can't find a property file to load
81          if (!propsFile.exists())
82          {
83              Log.warn("No property file found");
84              throw new IllegalStateException ("No property file specified in login module configuration file");
85          }
86              
87          
88       
89          try
90          {
91              this.propertyFileName = propsFile.getCanonicalPath();
92              if (fileMap.get(propertyFileName) != null)
93              {
94                  if (Log.isDebugEnabled()) {Log.debug("Properties file "+propertyFileName+" already in cache, skipping load");}
95                  return;
96              }
97              
98              Map userInfoMap = new HashMap();
99              Properties props = new Properties();
100             props.load(new FileInputStream(propsFile));
101             Iterator iter = props.entrySet().iterator();
102             while(iter.hasNext())
103             {
104                 
105                 Map.Entry entry = (Map.Entry)iter.next();
106                 String username=entry.getKey().toString().trim();
107                 String credentials=entry.getValue().toString().trim();
108                 String roles=null;
109                 int c=credentials.indexOf(',');
110                 if (c>0)
111                 {
112                     roles=credentials.substring(c+1).trim();
113                     credentials=credentials.substring(0,c).trim();
114                 }
115 
116                 if (username!=null && username.length()>0 &&
117                     credentials!=null && credentials.length()>0)
118                 {
119                     ArrayList roleList = new ArrayList();
120                     if(roles!=null && roles.length()>0)
121                     {
122                         StringTokenizer tok = new StringTokenizer(roles,", ");
123                         
124                         while (tok.hasMoreTokens())
125                             roleList.add(tok.nextToken());
126                     }
127                     
128                     userInfoMap.put(username, (new UserInfo(username, Credential.getCredential(credentials.toString()), roleList)));
129                 }
130             }
131             
132             fileMap.put(propertyFileName, userInfoMap);
133         }
134         catch (Exception e)
135         {
136             Log.warn("Error loading properties from file", e);
137             throw new RuntimeException(e);
138         }
139     }
140 
141     /** 
142      * Don't implement this as we want to pre-fetch all of the
143      * users.
144      * @param username
145      * @throws Exception
146      */
147     public UserInfo getUserInfo (String username) throws Exception
148     {
149         Map userInfoMap = (Map)fileMap.get(propertyFileName);
150         if (userInfoMap == null)
151             return null;
152         return (UserInfo)userInfoMap.get(username);
153     }
154 
155 }