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