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