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