1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mortbay.jetty.security;
17
18 import java.io.IOException;
19 import java.security.Principal;
20 import java.sql.Connection;
21 import java.sql.DriverManager;
22 import java.sql.PreparedStatement;
23 import java.sql.ResultSet;
24 import java.sql.SQLException;
25 import java.util.Properties;
26
27 import org.mortbay.jetty.Request;
28 import org.mortbay.jetty.UserRealm;
29 import org.mortbay.log.Log;
30 import org.mortbay.resource.Resource;
31 import org.mortbay.util.Loader;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class JDBCUserRealm extends HashUserRealm implements UserRealm
58 {
59
60 private String _jdbcDriver;
61 private String _url;
62 private String _userName;
63 private String _password;
64 private String _userTable;
65 private String _userTableKey;
66 private String _userTableUserField;
67 private String _userTablePasswordField;
68 private String _roleTable;
69 private String _roleTableKey;
70 private String _roleTableRoleField;
71 private String _userRoleTable;
72 private String _userRoleTableUserKey;
73 private String _userRoleTableRoleKey;
74 private int _cacheTime;
75
76 private long _lastHashPurge;
77 private Connection _con;
78 private String _userSql;
79 private String _roleSql;
80
81
82
83
84 public JDBCUserRealm()
85 {
86 super();
87 }
88
89
90
91
92
93 public JDBCUserRealm(String name)
94 {
95 super(name);
96 }
97
98
99
100
101
102
103
104
105 public JDBCUserRealm(String name, String config)
106 throws IOException,
107 ClassNotFoundException,
108 InstantiationException,
109 IllegalAccessException
110 {
111 super(name);
112 setConfig(config);
113 Loader.loadClass(this.getClass(),_jdbcDriver).newInstance();
114 connectDatabase();
115 }
116
117
118
119
120
121
122 protected void loadConfig()
123 throws IOException
124 {
125 Properties properties = new Properties();
126
127 properties.load(getConfigResource().getInputStream());
128
129 _jdbcDriver = properties.getProperty("jdbcdriver");
130 _url = properties.getProperty("url");
131 _userName = properties.getProperty("username");
132 _password = properties.getProperty("password");
133 _userTable = properties.getProperty("usertable");
134 _userTableKey = properties.getProperty("usertablekey");
135 _userTableUserField = properties.getProperty("usertableuserfield");
136 _userTablePasswordField = properties.getProperty("usertablepasswordfield");
137 _roleTable = properties.getProperty("roletable");
138 _roleTableKey = properties.getProperty("roletablekey");
139 _roleTableRoleField = properties.getProperty("roletablerolefield");
140 _userRoleTable = properties.getProperty("userroletable");
141 _userRoleTableUserKey = properties.getProperty("userroletableuserkey");
142 _userRoleTableRoleKey = properties.getProperty("userroletablerolekey");
143
144 String cachetime = properties.getProperty("cachetime");
145 _cacheTime = cachetime!=null ? new Integer(cachetime).intValue() : 30;
146
147 if (_jdbcDriver == null || _jdbcDriver.equals("")
148 || _url == null || _url.equals("")
149 || _userName == null || _userName.equals("")
150 || _password == null
151 || _cacheTime < 0)
152 {
153 if(Log.isDebugEnabled())Log.debug("UserRealm " + getName()
154 + " has not been properly configured");
155 }
156 _cacheTime *= 1000;
157 _lastHashPurge = 0;
158 _userSql = "select " + _userTableKey + ","
159 + _userTablePasswordField + " from "
160 + _userTable + " where "
161 + _userTableUserField + " = ?";
162 _roleSql = "select r." + _roleTableRoleField
163 + " from " + _roleTable + " r, "
164 + _userRoleTable + " u where u."
165 + _userRoleTableUserKey + " = ?"
166 + " and r." + _roleTableKey + " = u."
167 + _userRoleTableRoleKey;
168 }
169
170
171 public void logout(Principal user)
172 {}
173
174
175
176
177 public void connectDatabase()
178 {
179 try
180 {
181 Class.forName(_jdbcDriver);
182 _con = DriverManager.getConnection(_url, _userName, _password);
183 }
184 catch(SQLException e)
185 {
186 Log.warn("UserRealm " + getName()
187 + " could not connect to database; will try later", e);
188 }
189 catch(ClassNotFoundException e)
190 {
191 Log.warn("UserRealm " + getName()
192 + " could not connect to database; will try later", e);
193 }
194 }
195
196
197 public Principal authenticate(String username,
198 Object credentials,
199 Request request)
200 {
201 synchronized (this)
202 {
203 long now = System.currentTimeMillis();
204 if (now - _lastHashPurge > _cacheTime || _cacheTime == 0)
205 {
206 _users.clear();
207 _roles.clear();
208 _lastHashPurge = now;
209 }
210 Principal user = super.getPrincipal(username);
211 if (user == null)
212 {
213 loadUser(username);
214 user = super.getPrincipal(username);
215 }
216 }
217 return super.authenticate(username, credentials, request);
218 }
219
220
221
222
223
224
225
226 public synchronized boolean isUserInRole(Principal user, String roleName)
227 {
228 if(super.getPrincipal(user.getName())==null)
229 loadUser(user.getName());
230 return super.isUserInRole(user, roleName);
231 }
232
233
234
235
236
237 private void loadUser(String username)
238 {
239 try
240 {
241 if (null==_con)
242 connectDatabase();
243
244 if (null==_con)
245 throw new SQLException("Can't connect to database");
246
247 PreparedStatement stat = _con.prepareStatement(_userSql);
248 stat.setObject(1, username);
249 ResultSet rs = stat.executeQuery();
250
251 if (rs.next())
252 {
253 int key = rs.getInt(_userTableKey);
254 put(username, rs.getString(_userTablePasswordField));
255 stat.close();
256
257 stat = _con.prepareStatement(_roleSql);
258 stat.setInt(1, key);
259 rs = stat.executeQuery();
260
261 while (rs.next())
262 addUserToRole(username, rs.getString(_roleTableRoleField));
263
264 stat.close();
265 }
266 }
267 catch (SQLException e)
268 {
269 Log.warn("UserRealm " + getName()
270 + " could not load user information from database", e);
271 connectDatabase();
272 }
273 }
274 }