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  import org.eclipse.jetty.util.log.Logger;
31  
32  /**
33   * PropertyFileLoginModule
34   *
35   *
36   */
37  public class PropertyFileLoginModule extends AbstractLoginModule
38  {
39      private static final Logger LOG = Log.getLogger(PropertyFileLoginModule.class);
40  
41      public static final String DEFAULT_FILENAME = "realm.properties";
42      public static final Map<String, Map<String, UserInfo>> fileMap = new HashMap<String, Map<String, UserInfo>>(); 
43      
44      private String propertyFileName;
45      
46      
47  
48      /** 
49       * Read contents of the configured property file.
50       * 
51       * @see javax.security.auth.spi.LoginModule#initialize(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler, java.util.Map, java.util.Map)
52       * @param subject
53       * @param callbackHandler
54       * @param sharedState
55       * @param options
56       */
57      public void initialize(Subject subject, CallbackHandler callbackHandler,
58              Map<String,?> sharedState, Map<String,?> options)
59      {
60          super.initialize(subject, callbackHandler, sharedState, options);
61          loadProperties((String)options.get("file"));
62      }
63      
64    
65      
66      public void loadProperties (String filename)
67      {
68          File propsFile;
69          
70          if (filename == null)
71          {
72              propsFile = new File(System.getProperty("user.dir"), DEFAULT_FILENAME);
73              //look for a file called realm.properties in the current directory
74              //if that fails, look for a file called realm.properties in $jetty.home/etc
75              if (!propsFile.exists())
76                  propsFile = new File(System.getProperty("jetty.home"), DEFAULT_FILENAME);
77          }
78          else
79          {
80              propsFile = new File(filename);
81          }
82          
83          //give up, can't find a property file to load
84          if (!propsFile.exists())
85          {
86              LOG.warn("No property file found");
87              throw new IllegalStateException ("No property file specified in login module configuration file");
88          }
89              
90          
91       
92          try
93          {
94              this.propertyFileName = propsFile.getCanonicalPath();
95              if (fileMap.get(propertyFileName) != null)
96              {
97                  if (LOG.isDebugEnabled()) {LOG.debug("Properties file "+propertyFileName+" already in cache, skipping load");}
98                  return;
99              }
100             
101             Map<String, UserInfo> userInfoMap = new HashMap<String, UserInfo>();
102             Properties props = new Properties();
103             props.load(new FileInputStream(propsFile));
104             Iterator<Map.Entry<Object,Object>> iter = props.entrySet().iterator();
105             while(iter.hasNext())
106             {
107                 
108                 Map.Entry<Object,Object> entry = iter.next();
109                 String username=entry.getKey().toString().trim();
110                 String credentials=entry.getValue().toString().trim();
111                 String roles=null;
112                 int c=credentials.indexOf(',');
113                 if (c>0)
114                 {
115                     roles=credentials.substring(c+1).trim();
116                     credentials=credentials.substring(0,c).trim();
117                 }
118 
119                 if (username!=null && username.length()>0 &&
120                     credentials!=null && credentials.length()>0)
121                 {
122                     ArrayList<String> roleList = new ArrayList<String>();
123                     if(roles!=null && roles.length()>0)
124                     {
125                         StringTokenizer tok = new StringTokenizer(roles,", ");
126                         
127                         while (tok.hasMoreTokens())
128                             roleList.add(tok.nextToken());
129                     }
130                     
131                     userInfoMap.put(username, (new UserInfo(username, Credential.getCredential(credentials.toString()), roleList)));
132                 }
133             }
134             
135             fileMap.put(propertyFileName, userInfoMap);
136         }
137         catch (Exception e)
138         {
139             LOG.warn("Error loading properties from file", e);
140             throw new RuntimeException(e);
141         }
142     }
143 
144     /** 
145      * Don't implement this as we want to pre-fetch all of the
146      * users.
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 }