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