KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > security > auth > spi > Util


1 /*
2  * JBoss, Home of Professional Open Source
3  *
4  * Distributable under LGPL license.
5  * See terms of license at gnu.org.
6  */

7
8 package org.jboss.security.auth.spi;
9
10 import java.util.Properties JavaDoc;
11 import java.util.Enumeration JavaDoc;
12 import java.util.ArrayList JavaDoc;
13 import java.util.StringTokenizer JavaDoc;
14 import java.util.HashMap JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.io.InputStream JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.net.URLClassLoader JavaDoc;
19 import java.security.acl.Group JavaDoc;
20 import java.security.Principal JavaDoc;
21 import java.sql.Connection JavaDoc;
22 import java.sql.PreparedStatement JavaDoc;
23 import java.sql.ResultSet JavaDoc;
24 import java.sql.SQLException JavaDoc;
25
26 import javax.security.auth.login.LoginException JavaDoc;
27 import javax.security.auth.login.FailedLoginException JavaDoc;
28 import javax.naming.InitialContext JavaDoc;
29 import javax.naming.NamingException JavaDoc;
30 import javax.sql.DataSource JavaDoc;
31
32 import org.jboss.logging.Logger;
33 import org.jboss.security.SimpleGroup;
34
35 /**
36  * Common login module utility methods
37  *
38  * @author Scott.Stark@jboss.org
39  * @version $Revision: 1.1 $
40  */

41 public class Util
42 {
43    /** Create the set of roles the user belongs to by parsing the roles.properties
44     data for username=role1,role2,... and username.XXX=role1,role2,...
45     patterns.
46     *
47     * @param targetUser - the username to obtain roles for
48     * @param roles - the Properties containing the user=roles mappings
49     * @param roleGroupSeperator - the character that seperates a username
50     * from a group name, e.g., targetUser[.GroupName]=roles
51     * @param aslm - the login module to use for Principal creation
52     * @return Group[] containing the sets of roles
53     */

54    static Group JavaDoc[] getRoleSets(String JavaDoc targetUser, Properties JavaDoc roles,
55       char roleGroupSeperator, AbstractServerLoginModule aslm)
56    {
57       Enumeration JavaDoc users = roles.propertyNames();
58       SimpleGroup rolesGroup = new SimpleGroup("Roles");
59       ArrayList JavaDoc groups = new ArrayList JavaDoc();
60       groups.add(rolesGroup);
61       while (users.hasMoreElements() && targetUser != null)
62       {
63          String JavaDoc user = (String JavaDoc) users.nextElement();
64          String JavaDoc value = roles.getProperty(user);
65          // See if this entry is of the form targetUser[.GroupName]=roles
66
int index = user.indexOf(roleGroupSeperator);
67          boolean isRoleGroup = false;
68          boolean userMatch = false;
69          if (index > 0 && targetUser.regionMatches(0, user, 0, index) == true)
70             isRoleGroup = true;
71          else
72             userMatch = targetUser.equals(user);
73
74          // Check for username.RoleGroup pattern
75
if (isRoleGroup == true)
76          {
77             String JavaDoc groupName = user.substring(index + 1);
78             if (groupName.equals("Roles"))
79                parseGroupMembers(rolesGroup, value, aslm);
80             else
81             {
82                SimpleGroup group = new SimpleGroup(groupName);
83                parseGroupMembers(group, value, aslm);
84                groups.add(group);
85             }
86          }
87          else if (userMatch == true)
88          {
89             // Place these roles into the Default "Roles" group
90
parseGroupMembers(rolesGroup, value, aslm);
91          }
92       }
93       Group JavaDoc[] roleSets = new Group JavaDoc[groups.size()];
94       groups.toArray(roleSets);
95       return roleSets;
96    }
97
98    /** Execute the rolesQuery against the dsJndiName to obtain the roles for
99     the authenticated user.
100      
101     @return Group[] containing the sets of roles
102     */

103    static Group JavaDoc[] getRoleSets(String JavaDoc username, String JavaDoc dsJndiName,
104       String JavaDoc rolesQuery, AbstractServerLoginModule aslm)
105       throws LoginException JavaDoc
106    {
107       Connection JavaDoc conn = null;
108       HashMap JavaDoc setsMap = new HashMap JavaDoc();
109       PreparedStatement JavaDoc ps = null;
110       ResultSet JavaDoc rs = null;
111
112       try
113       {
114          InitialContext JavaDoc ctx = new InitialContext JavaDoc();
115          DataSource JavaDoc ds = (DataSource JavaDoc) ctx.lookup(dsJndiName);
116          conn = ds.getConnection();
117          // Get the user role names
118
ps = conn.prepareStatement(rolesQuery);
119          try
120          {
121             ps.setString(1, username);
122          }
123          catch(ArrayIndexOutOfBoundsException JavaDoc ignore)
124          {
125             // The query may not have any parameters so just try it
126
}
127          rs = ps.executeQuery();
128          if( rs.next() == false )
129          {
130             if( aslm.getUnauthenticatedIdentity() == null )
131                throw new FailedLoginException JavaDoc("No matching username found in Roles");
132             /* We are running with an unauthenticatedIdentity so create an
133                empty Roles set and return.
134             */

135             Group JavaDoc[] roleSets = { new SimpleGroup("Roles") };
136             return roleSets;
137          }
138
139          do
140          {
141             String JavaDoc name = rs.getString(1);
142             String JavaDoc groupName = rs.getString(2);
143             if( groupName == null || groupName.length() == 0 )
144                groupName = "Roles";
145             Group JavaDoc group = (Group JavaDoc) setsMap.get(groupName);
146             if( group == null )
147             {
148                group = new SimpleGroup(groupName);
149                setsMap.put(groupName, group);
150             }
151
152             try
153             {
154                Principal JavaDoc p = aslm.createIdentity(name);
155                aslm.log.trace("Assign user to role " + name);
156                group.addMember(p);
157             }
158             catch(Exception JavaDoc e)
159             {
160                aslm.log.debug("Failed to create principal: "+name, e);
161             }
162          } while( rs.next() );
163       }
164       catch(NamingException JavaDoc ex)
165       {
166          throw new LoginException JavaDoc(ex.toString(true));
167       }
168       catch(SQLException JavaDoc ex)
169       {
170          aslm.log.error("SQL failure", ex);
171          throw new LoginException JavaDoc(ex.toString());
172       }
173       finally
174       {
175          if( rs != null )
176          {
177             try
178             {
179                rs.close();
180             }
181             catch(SQLException JavaDoc e)
182             {}
183          }
184          if( ps != null )
185          {
186             try
187             {
188                ps.close();
189             }
190             catch(SQLException JavaDoc e)
191             {}
192          }
193          if( conn != null )
194          {
195             try
196             {
197                conn.close();
198             }
199             catch (Exception JavaDoc ex)
200             {}
201          }
202       }
203       
204       Group JavaDoc[] roleSets = new Group JavaDoc[setsMap.size()];
205       setsMap.values().toArray(roleSets);
206       return roleSets;
207    }
208
209    /** Utility method which loads the given properties file and returns a
210     * Properties object containing the key,value pairs in that file.
211     * The properties files should be in the class path as this method looks
212     * to the thread context class loader (TCL) to locate the resource. If the
213     * TCL is a URLClassLoader the findResource(String) method is first tried.
214     * If this fails or the TCL is not a URLClassLoader getResource(String) is
215     * tried.
216     * @param defaultsName - the name of the default properties file resource
217     * that will be used as the default Properties to the ctor of the
218     * propertiesName Properties instance.
219     * @param propertiesName - the name of the properties file resource
220     * @param log - the logger used for trace level messages
221     * @return the loaded properties file if found
222     * @exception java.io.IOException thrown if the properties file cannot be found
223     * or loaded
224     */

225    static Properties JavaDoc loadProperties(String JavaDoc defaultsName, String JavaDoc propertiesName, Logger log)
226       throws IOException JavaDoc
227    {
228       Properties JavaDoc bundle = null;
229       ClassLoader JavaDoc loader = Thread.currentThread().getContextClassLoader();
230       URL JavaDoc defaultUrl = null;
231       URL JavaDoc url = null;
232       // First check for local visibility via a URLClassLoader.findResource
233
if( loader instanceof URLClassLoader JavaDoc )
234       {
235          URLClassLoader JavaDoc ucl = (URLClassLoader JavaDoc) loader;
236          defaultUrl = ucl.findResource(defaultsName);
237          url = ucl.findResource(propertiesName);
238          log.trace("findResource: "+url);
239       }
240       // Do a general resource search
241
if( defaultUrl == null )
242          defaultUrl = loader.getResource(defaultsName);
243       if( url == null )
244          url = loader.getResource(propertiesName);
245       if( url == null && defaultUrl == null )
246       {
247          String JavaDoc msg = "No properties file: " + propertiesName
248             + " or defaults: " +defaultsName+ " found";
249          throw new IOException JavaDoc(msg);
250       }
251
252       log.trace("Properties file=" + url+", defaults="+defaultUrl);
253       Properties JavaDoc defaults = new Properties JavaDoc();
254       if( defaultUrl != null )
255       {
256          try
257          {
258             InputStream JavaDoc is = defaultUrl.openStream();
259             defaults.load(is);
260             is.close();
261             log.debug("Loaded defaults, users="+defaults.keySet());
262          }
263          catch(Throwable JavaDoc e)
264          {
265             log.debug("Failed to load defaults", e);
266          }
267       }
268
269       bundle = new Properties JavaDoc(defaults);
270       if( url != null )
271       {
272          InputStream JavaDoc is = url.openStream();
273          if (is != null)
274          {
275             bundle.load(is);
276             is.close();
277          }
278          else
279          {
280             throw new IOException JavaDoc("Properties file " + propertiesName + " not avilable");
281          }
282          log.debug("Loaded properties, users="+bundle.keySet());
283       }
284
285       return bundle;
286    }
287
288    /** Parse the comma delimited roles names given by value and add them to
289     * group. The type of Principal created for each name is determined by
290     * the createIdentity method.
291     *
292     * @see AbstractServerLoginModule#createIdentity(String)
293     *
294     * @param group - the Group to add the roles to.
295     * @param roles - the comma delimited role names.
296     */

297    static void parseGroupMembers(Group JavaDoc group, String JavaDoc roles,
298       AbstractServerLoginModule aslm)
299    {
300       StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(roles, ",");
301       while (tokenizer.hasMoreTokens())
302       {
303          String JavaDoc token = tokenizer.nextToken();
304          try
305          {
306             Principal JavaDoc p = aslm.createIdentity(token);
307             group.addMember(p);
308          }
309          catch (Exception JavaDoc e)
310          {
311             aslm.log.warn("Failed to create principal for: "+token, e);
312          }
313       }
314    }
315 }
316
Popular Tags