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