1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.mortbay.jetty.plus.security;
18
19 import java.io.IOException;
20 import java.security.Principal;
21 import java.sql.Connection;
22 import java.sql.PreparedStatement;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.util.Properties;
26
27 import javax.naming.InitialContext;
28 import javax.naming.NameNotFoundException;
29 import javax.naming.NamingException;
30 import javax.sql.DataSource;
31
32 import org.mortbay.jetty.Request;
33 import org.mortbay.jetty.Server;
34 import org.mortbay.jetty.plus.naming.NamingEntryUtil;
35 import org.mortbay.jetty.security.HashUserRealm;
36 import org.mortbay.log.Log;
37
38
39
40
41
42
43
44
45
46 public class DataSourceUserRealm extends HashUserRealm
47 {
48 private String _jndiName = "javax.sql.DataSource/default";
49 private DataSource _datasource;
50 private Server _server;
51 private String _userTableName = "users";
52 private String _userTableKey = "id";
53 private String _userTableUserField = "username";
54 private String _userTablePasswordField = "pwd";
55 private String _roleTableName = "roles";
56 private String _roleTableKey = "id";
57 private String _roleTableRoleField = "role";
58 private String _userRoleTableName = "user_roles";
59 private String _userRoleTableUserKey = "user_id";
60 private String _userRoleTableRoleKey = "role_id";
61 private int _cacheMs = 30000;
62 private long _lastHashPurge = 0;
63 private String _userSql;
64 private String _roleSql;
65
66
67
68 public DataSourceUserRealm (String jndiName)
69 {
70 _jndiName=jndiName;
71 }
72
73
74 public DataSourceUserRealm()
75 {
76 }
77
78
79 public void setServer (Server server)
80 {
81 _server=server;
82 }
83
84 public Server getServer()
85 {
86 return _server;
87 }
88
89 public void setUserTableName (String name)
90 {
91 _userTableName=name;
92 }
93
94 public String getUserTableName()
95 {
96 return _userTableName;
97 }
98
99 public String getUserTableKey()
100 {
101 return _userTableKey;
102 }
103
104
105 public void setUserTableKey(String tableKey)
106 {
107 _userTableKey = tableKey;
108 }
109
110
111 public String getUserTableUserField()
112 {
113 return _userTableUserField;
114 }
115
116
117 public void setUserTableUserField(String tableUserField)
118 {
119 _userTableUserField = tableUserField;
120 }
121
122
123 public String getUserTablePasswordField()
124 {
125 return _userTablePasswordField;
126 }
127
128
129 public void setUserTablePasswordField(String tablePasswordField)
130 {
131 _userTablePasswordField = tablePasswordField;
132 }
133
134
135 public String getRoleTableName()
136 {
137 return _roleTableName;
138 }
139
140
141 public void setRoleTableName(String tableName)
142 {
143 _roleTableName = tableName;
144 }
145
146
147 public String getRoleTableKey()
148 {
149 return _roleTableKey;
150 }
151
152
153 public void setRoleTableKey(String tableKey)
154 {
155 _roleTableKey = tableKey;
156 }
157
158
159 public String getRoleTableRoleField()
160 {
161 return _roleTableRoleField;
162 }
163
164
165 public void setRoleTableRoleField(String tableRoleField)
166 {
167 _roleTableRoleField = tableRoleField;
168 }
169
170
171 public String getUserRoleTableName()
172 {
173 return _userRoleTableName;
174 }
175
176
177 public void setUserRoleTableName(String roleTableName)
178 {
179 _userRoleTableName = roleTableName;
180 }
181
182
183 public String getUserRoleTableUserKey()
184 {
185 return _userRoleTableUserKey;
186 }
187
188
189 public void setUserRoleTableUserKey(String roleTableUserKey)
190 {
191 _userRoleTableUserKey = roleTableUserKey;
192 }
193
194
195 public String getUserRoleTableRoleKey()
196 {
197 return _userRoleTableRoleKey;
198 }
199
200
201 public void setUserRoleTableRoleKey(String roleTableRoleKey)
202 {
203 _userRoleTableRoleKey = roleTableRoleKey;
204 }
205
206 public void setCacheMs (int ms)
207 {
208 _cacheMs=ms;
209 }
210
211 public int getCacheMs ()
212 {
213 return _cacheMs;
214 }
215
216
217
218
219
220
221
222 public Principal authenticate(String username,
223 Object credentials,
224 Request request)
225 {
226 synchronized (this)
227 {
228 long now = System.currentTimeMillis();
229 if (now - _lastHashPurge > _cacheMs || _cacheMs == 0)
230 {
231 _users.clear();
232 _roles.clear();
233 _lastHashPurge = now;
234 }
235 Principal user = super.getPrincipal(username);
236 if (user == null)
237 {
238 loadUser(username);
239 user = super.getPrincipal(username);
240 }
241 }
242 return super.authenticate(username, credentials, request);
243 }
244
245
246
247
248
249
250
251 public synchronized boolean isUserInRole(Principal user, String roleName)
252 {
253 if(super.getPrincipal(user.getName())==null)
254 loadUser(user.getName());
255 return super.isUserInRole(user, roleName);
256 }
257
258
259
260
261
262
263
264
265 protected void loadConfig()
266 throws IOException
267 {
268 Properties properties = new Properties();
269
270 properties.load(getConfigResource().getInputStream());
271
272 _jndiName = properties.getProperty("jndiname");
273 setUserTableName(properties.getProperty("usertable"));
274 setUserTableKey(properties.getProperty("usertablekey"));
275 setUserTableUserField(properties.getProperty("usertableuserfield"));
276 setUserTablePasswordField(properties.getProperty("usertablepasswordfield"));
277 setRoleTableName(properties.getProperty("roletable"));
278 setRoleTableKey(properties.getProperty("roletablekey"));
279 setRoleTableRoleField(properties.getProperty("roletablerolefield"));
280 setUserRoleTableName(properties.getProperty("userroletable"));
281 setUserRoleTableUserKey(properties.getProperty("userroletableuserkey"));
282 setUserRoleTableRoleKey(properties.getProperty("userroletablerolekey"));
283
284 String cacheSec = properties.getProperty("cachetime");
285 if (cacheSec != null)
286 setCacheMs(new Integer(cacheSec).intValue() * 1000);
287
288 if (_jndiName == null || _cacheMs < 0)
289 {
290 if(Log.isDebugEnabled())Log.debug("UserRealm " + getName()
291 + " has not been properly configured");
292 }
293 }
294
295
296
297
298
299
300 private void loadUser (String user)
301 {
302 Connection connection = null;
303 try
304 {
305 initDb();
306 connection = getConnection();
307
308 PreparedStatement statement = connection.prepareStatement(_userSql);
309 statement.setObject(1, user);
310 ResultSet rs = statement.executeQuery();
311
312 if (rs.next())
313 {
314 int key = rs.getInt(_userTableKey);
315 put(user, rs.getString(_userTablePasswordField));
316 statement.close();
317
318 statement = connection.prepareStatement(_roleSql);
319 statement.setInt(1, key);
320 rs = statement.executeQuery();
321
322 while (rs.next())
323 addUserToRole(user, rs.getString(_roleTableRoleField));
324
325 statement.close();
326 }
327 }
328 catch (NamingException e)
329 {
330 Log.warn("No datasource for "+_jndiName, e);
331 }
332 catch (SQLException e)
333 {
334 Log.warn("Problem loading user info for "+user, e);
335 }
336 finally
337 {
338 if (connection != null)
339 {
340 try
341 {
342 connection.close();
343 }
344 catch (SQLException x)
345 {
346 Log.warn("Problem closing connection", x);
347 }
348 finally
349 {
350 connection = null;
351 }
352 }
353 }
354 }
355
356
357
358
359
360
361
362
363
364 private void initDb() throws NamingException
365 {
366 if (_datasource != null)
367 return;
368
369 InitialContext ic = new InitialContext();
370
371 try
372 {
373 _datasource = (DataSource)NamingEntryUtil.lookup(_server, _jndiName);
374 }
375 catch (NameNotFoundException e)
376 {
377
378 }
379
380
381 if (_datasource==null)
382 {
383 _datasource = (DataSource)NamingEntryUtil.lookup(null, _jndiName);
384 }
385
386 _userSql = "select " + _userTableKey + "," + _userTablePasswordField
387 + " from " + _userTableName
388 + " where "+ _userTableUserField + " = ?";
389
390 _roleSql = "select r." + _roleTableRoleField
391 + " from " + _roleTableName + " r, " + _userRoleTableName
392 + " u where u."+ _userRoleTableUserKey + " = ?"
393 + " and r." + _roleTableKey + " = u." + _userRoleTableRoleKey;
394 }
395
396 private Connection getConnection ()
397 throws NamingException, SQLException
398 {
399 initDb();
400 return _datasource.getConnection();
401 }
402
403 }