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.sql.Connection;
23 import java.sql.DriverManager;
24 import java.sql.PreparedStatement;
25 import java.sql.ResultSet;
26 import java.sql.SQLException;
27 import java.util.ArrayList;
28 import java.util.List;
29 import java.util.Properties;
30
31 import org.eclipse.jetty.server.UserIdentity;
32 import org.eclipse.jetty.util.Loader;
33 import org.eclipse.jetty.util.log.Log;
34 import org.eclipse.jetty.util.log.Logger;
35 import org.eclipse.jetty.util.resource.Resource;
36 import org.eclipse.jetty.util.security.Credential;
37
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 private String _config;
65 private String _jdbcDriver;
66 private String _url;
67 private String _userName;
68 private String _password;
69 private String _userTableKey;
70 private String _userTablePasswordField;
71 private String _roleTableRoleField;
72 private int _cacheTime;
73 private long _lastHashPurge;
74 private Connection _con;
75 private String _userSql;
76 private 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 properties.load(resource.getInputStream());
120
121 _jdbcDriver = properties.getProperty("jdbcdriver");
122 _url = properties.getProperty("url");
123 _userName = properties.getProperty("username");
124 _password = properties.getProperty("password");
125 String _userTable = properties.getProperty("usertable");
126 _userTableKey = properties.getProperty("usertablekey");
127 String _userTableUserField = properties.getProperty("usertableuserfield");
128 _userTablePasswordField = properties.getProperty("usertablepasswordfield");
129 String _roleTable = properties.getProperty("roletable");
130 String _roleTableKey = properties.getProperty("roletablekey");
131 _roleTableRoleField = properties.getProperty("roletablerolefield");
132 String _userRoleTable = properties.getProperty("userroletable");
133 String _userRoleTableUserKey = properties.getProperty("userroletableuserkey");
134 String _userRoleTableRoleKey = properties.getProperty("userroletablerolekey");
135 _cacheTime = new Integer(properties.getProperty("cachetime"));
136
137 if (_jdbcDriver == null || _jdbcDriver.equals("")
138 || _url == null
139 || _url.equals("")
140 || _userName == null
141 || _userName.equals("")
142 || _password == null
143 || _cacheTime < 0)
144 {
145 LOG.warn("UserRealm " + getName() + " has not been properly configured");
146 }
147 _cacheTime *= 1000;
148 _lastHashPurge = 0;
149 _userSql = "select " + _userTableKey + "," + _userTablePasswordField + " from " + _userTable + " where " + _userTableUserField + " = ?";
150 _roleSql = "select r." + _roleTableRoleField
151 + " from "
152 + _roleTable
153 + " r, "
154 + _userRoleTable
155 + " u where u."
156 + _userRoleTableUserKey
157 + " = ?"
158 + " and r."
159 + _roleTableKey
160 + " = u."
161 + _userRoleTableRoleKey;
162
163 Loader.loadClass(this.getClass(), _jdbcDriver).newInstance();
164 super.doStart();
165 }
166
167
168
169 public String getConfig()
170 {
171 return _config;
172 }
173
174
175
176
177
178
179
180 public void setConfig(String config)
181 {
182 if (isRunning())
183 throw new IllegalStateException("Running");
184 _config=config;
185 }
186
187
188
189
190
191 public void connectDatabase()
192 {
193 try
194 {
195 Class.forName(_jdbcDriver);
196 _con = DriverManager.getConnection(_url, _userName, _password);
197 }
198 catch (SQLException e)
199 {
200 LOG.warn("UserRealm " + getName() + " could not connect to database; will try later", e);
201 }
202 catch (ClassNotFoundException e)
203 {
204 LOG.warn("UserRealm " + getName() + " could not connect to database; will try later", e);
205 }
206 }
207
208
209 @Override
210 public UserIdentity login(String username, Object credentials)
211 {
212 long now = System.currentTimeMillis();
213 if (now - _lastHashPurge > _cacheTime || _cacheTime == 0)
214 {
215 _users.clear();
216 _lastHashPurge = now;
217 closeConnection();
218 }
219
220 return super.login(username,credentials);
221 }
222
223
224 @Override
225 protected void loadUsers()
226 {
227 }
228
229
230 @Override
231 protected UserIdentity loadUser(String username)
232 {
233 try
234 {
235 if (null == _con)
236 connectDatabase();
237
238 if (null == _con)
239 throw new SQLException("Can't connect to database");
240
241 PreparedStatement stat = _con.prepareStatement(_userSql);
242 stat.setObject(1, username);
243 ResultSet rs = stat.executeQuery();
244
245 if (rs.next())
246 {
247 int key = rs.getInt(_userTableKey);
248 String credentials = rs.getString(_userTablePasswordField);
249 stat.close();
250
251 stat = _con.prepareStatement(_roleSql);
252 stat.setInt(1, key);
253 rs = stat.executeQuery();
254 List<String> roles = new ArrayList<String>();
255 while (rs.next())
256 roles.add(rs.getString(_roleTableRoleField));
257
258 stat.close();
259 return putUser(username, Credential.getCredential(credentials),roles.toArray(new String[roles.size()]));
260 }
261 }
262 catch (SQLException e)
263 {
264 LOG.warn("UserRealm " + getName() + " could not load user information from database", e);
265 closeConnection();
266 }
267 return null;
268 }
269
270
271
272
273 private void closeConnection ()
274 {
275 if (_con != null)
276 {
277 if (LOG.isDebugEnabled()) LOG.debug("Closing db connection for JDBCUserRealm");
278 try { _con.close(); }catch (Exception e) {LOG.ignore(e);}
279 }
280 _con = null;
281 }
282
283 }