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.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 public void setConfig(String config)
173 {
174 if (isRunning())
175 throw new IllegalStateException("Running");
176 _config=config;
177 }
178
179
180
181
182
183 public void connectDatabase()
184 {
185 try
186 {
187 Class.forName(_jdbcDriver);
188 _con = DriverManager.getConnection(_url, _userName, _password);
189 }
190 catch (SQLException e)
191 {
192 Log.warn("UserRealm " + getName() + " could not connect to database; will try later", e);
193 }
194 catch (ClassNotFoundException e)
195 {
196 Log.warn("UserRealm " + getName() + " could not connect to database; will try later", e);
197 }
198 }
199
200
201 @Override
202 public UserIdentity login(String username, Object credentials)
203 {
204 long now = System.currentTimeMillis();
205 if (now - _lastHashPurge > _cacheTime || _cacheTime == 0)
206 {
207 _users.clear();
208 _lastHashPurge = now;
209 closeConnection();
210 }
211
212 return super.login(username,credentials);
213 }
214
215
216 @Override
217 protected void loadUsers()
218 {
219 }
220
221
222 @Override
223 protected UserIdentity loadUser(String username)
224 {
225 try
226 {
227 if (null == _con)
228 connectDatabase();
229
230 if (null == _con)
231 throw new SQLException("Can't connect to database");
232
233 PreparedStatement stat = _con.prepareStatement(_userSql);
234 stat.setObject(1, username);
235 ResultSet rs = stat.executeQuery();
236
237 if (rs.next())
238 {
239 int key = rs.getInt(_userTableKey);
240 String credentials = rs.getString(_userTablePasswordField);
241 stat.close();
242
243 stat = _con.prepareStatement(_roleSql);
244 stat.setInt(1, key);
245 rs = stat.executeQuery();
246 List<String> roles = new ArrayList<String>();
247 while (rs.next())
248 roles.add(rs.getString(_roleTableRoleField));
249
250 stat.close();
251 return putUser(username, Credential.getCredential(credentials),roles.toArray(new String[roles.size()]));
252 }
253 }
254 catch (SQLException e)
255 {
256 Log.warn("UserRealm " + getName() + " could not load user information from database", e);
257 closeConnection();
258 }
259 return null;
260 }
261
262
263
264
265 private void closeConnection ()
266 {
267 if (_con != null)
268 {
269 if (Log.isDebugEnabled()) Log.debug("Closing db connection for JDBCUserRealm");
270 try { _con.close(); }catch (Exception e) {Log.ignore(e);}
271 }
272 _con = null;
273 }
274
275 }