KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > http > JDBCUserRealm


1 // ========================================================================
2
// $Id: JDBCUserRealm.java,v 1.20 2006/04/05 12:59:16 janb Exp $
3
// Copyright 2003-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.http;
17
18 import java.io.IOException JavaDoc;
19 import java.security.Principal JavaDoc;
20 import java.sql.Connection JavaDoc;
21 import java.sql.DriverManager JavaDoc;
22 import java.sql.PreparedStatement JavaDoc;
23 import java.sql.ResultSet JavaDoc;
24 import java.sql.SQLException JavaDoc;
25 import java.util.Properties JavaDoc;
26
27 import org.apache.commons.logging.Log;
28 import org.mortbay.log.LogFactory;
29 import org.mortbay.util.Loader;
30 import org.mortbay.util.Resource;
31
32 /* ------------------------------------------------------------ */
33 /** HashMapped User Realm with JDBC as data source.
34  * JDBCUserRealm extends HashUserRealm and adds a method to fetch user
35  * information from database.
36  * The authenticate() method checks the inherited HashMap for the user.
37  * If the user is not found, it will fetch details from the database
38  * and populate the inherited HashMap. It then calls the HashUserRealm
39  * authenticate() method to perform the actual authentication.
40  * Periodically (controlled by configuration parameter), internal
41  * hashes are cleared. Caching can be disabled by setting cache
42  * refresh interval to zero.
43  * Uses one database connection that is initialized at startup. Reconnect
44  * on failures. authenticate() is 'synchronized'.
45  *
46  * An example properties file for configuration is in
47  * $JETTY_HOME/etc/jdbcRealm.properties
48  *
49  * @version $Id: JDBCUserRealm.java,v 1.20 2006/04/05 12:59:16 janb Exp $
50  * @author Arkadi Shishlov (arkadi)
51  * @author Fredrik Borgh
52  * @author Greg Wilkins (gregw)
53  * @author Ben Alex
54  */

55
56 public class JDBCUserRealm extends HashUserRealm
57 {
58     private static Log log = LogFactory.getLog(JDBCUserRealm.class);
59
60     private String JavaDoc _jdbcDriver;
61     private String JavaDoc _url;
62     private String JavaDoc _userName;
63     private String JavaDoc _password;
64     private String JavaDoc _userTable;
65     private String JavaDoc _userTableKey;
66     private String JavaDoc _userTableUserField;
67     private String JavaDoc _userTablePasswordField;
68     private String JavaDoc _roleTable;
69     private String JavaDoc _roleTableKey;
70     private String JavaDoc _roleTableRoleField;
71     private String JavaDoc _userRoleTable;
72     private String JavaDoc _userRoleTableUserKey;
73     private String JavaDoc _userRoleTableRoleKey;
74     private int _cacheTime;
75     
76     private long _lastHashPurge;
77     private Connection JavaDoc _con;
78     private String JavaDoc _userSql;
79     private String JavaDoc _roleSql;
80     
81     /* ------------------------------------------------------------ */
82     /** Constructor.
83      * @param name
84      */

85     public JDBCUserRealm(String JavaDoc name)
86     {
87         super(name);
88     }
89     
90     /* ------------------------------------------------------------ */
91     /** Constructor.
92      * @param name Realm name
93      * @param config Filename or url of JDBC connection properties file.
94      * @exception IOException
95      * @exception ClassNotFoundException
96      */

97     public JDBCUserRealm(String JavaDoc name, String JavaDoc config)
98         throws IOException JavaDoc,
99                ClassNotFoundException JavaDoc,
100                InstantiationException JavaDoc,
101                IllegalAccessException JavaDoc
102     {
103         super(name);
104         loadConfig(config);
105         Loader.loadClass(this.getClass(),_jdbcDriver).newInstance();
106         connectDatabase();
107     }
108     
109     /* ------------------------------------------------------------ */
110     /** Load JDBC connection configuration from properties file.
111      *
112      * @param config Filename or url of user properties file.
113      * @exception IOException
114      */

115     public void loadConfig(String JavaDoc config)
116         throws IOException JavaDoc
117     {
118         Properties JavaDoc properties = new Properties JavaDoc();
119         Resource resource=Resource.newResource(config);
120         properties.load(resource.getInputStream());
121         
122         _jdbcDriver = properties.getProperty("jdbcdriver");
123         _url = properties.getProperty("url");
124         _userName = properties.getProperty("username");
125         _password = properties.getProperty("password");
126         _userTable = properties.getProperty("usertable");
127         _userTableKey = properties.getProperty("usertablekey");
128         _userTableUserField = properties.getProperty("usertableuserfield");
129         _userTablePasswordField = properties.getProperty("usertablepasswordfield");
130         _roleTable = properties.getProperty("roletable");
131         _roleTableKey = properties.getProperty("roletablekey");
132         _roleTableRoleField = properties.getProperty("roletablerolefield");
133         _userRoleTable = properties.getProperty("userroletable");
134         _userRoleTableUserKey = properties.getProperty("userroletableuserkey");
135         _userRoleTableRoleKey = properties.getProperty("userroletablerolekey");
136         _cacheTime = new Integer JavaDoc(properties.getProperty("cachetime")).intValue();
137         
138         if (_jdbcDriver == null || _jdbcDriver.equals("")
139             || _url == null || _url.equals("")
140             || _userName == null || _userName.equals("")
141             || _password == null
142             || _cacheTime < 0)
143         {
144             if(log.isDebugEnabled())log.debug("UserRealm " + getName()
145                         + " has not been properly configured");
146         }
147         _cacheTime *= 1000;
148         _lastHashPurge = 0;
149         _userSql = "select " + _userTableKey + ","
150             + _userTablePasswordField + " from "
151             + _userTable + " where "
152             + _userTableUserField + " = ?";
153         _roleSql = "select r." + _roleTableRoleField
154             + " from " + _roleTable + " r, "
155             + _userRoleTable + " u where u."
156             + _userRoleTableUserKey + " = ?"
157             + " and r." + _roleTableKey + " = u."
158             + _userRoleTableRoleKey;
159     }
160
161     /* ------------------------------------------------------------ */
162     public void logout(Principal JavaDoc user)
163     {
164         remove(user.getName());
165     }
166     
167     /* ------------------------------------------------------------ */
168     /** (re)Connect to database with parameters setup by loadConfig()
169      */

170     public void connectDatabase()
171     {
172         try
173         {
174             _con = DriverManager.getConnection(_url, _userName, _password);
175         }
176         catch(SQLException JavaDoc e)
177         {
178             log.warn("UserRealm " + getName()
179                       + " could not connect to database; will try later", e);
180         }
181     }
182     
183     /* ------------------------------------------------------------ */
184     public Principal JavaDoc authenticate(String JavaDoc username,
185                                   Object JavaDoc credentials,
186                                   HttpRequest request)
187     {
188
189         synchronized(this)
190         {
191             long now = System.currentTimeMillis();
192             if (now - _lastHashPurge > _cacheTime || _cacheTime == 0)
193             {
194                 super.clear();
195                 _roles.clear();
196                 _lastHashPurge = now;
197             }
198             Principal JavaDoc user = (Principal JavaDoc)super.get(username);
199             if (user == null)
200             {
201                 loadUser(username);
202                 user = (Principal JavaDoc)super.get(username);
203             }
204         }
205         return super.authenticate(username, credentials, request);
206     }
207     
208    
209     
210     /* ------------------------------------------------------------ */
211     private void loadUser(String JavaDoc username)
212     {
213         try
214         {
215             if (null==_con)
216                 connectDatabase();
217             
218             if (null==_con)
219                 throw new SQLException JavaDoc("Can't connect to database");
220             
221             PreparedStatement JavaDoc stat = _con.prepareStatement(_userSql);
222             stat.setObject(1, username);
223             ResultSet JavaDoc rs = stat.executeQuery();
224     
225             if (rs.next())
226             {
227                 Object JavaDoc key = rs.getObject(_userTableKey);
228                 put(username, rs.getString(_userTablePasswordField));
229                 stat.close();
230                 
231                 stat = _con.prepareStatement(_roleSql);
232                 stat.setObject(1, key);
233                 rs = stat.executeQuery();
234
235                 while (rs.next())
236                     addUserToRole(username, rs.getString(_roleTableRoleField));
237                 
238                 stat.close();
239             }
240         }
241         catch (SQLException JavaDoc e)
242         {
243             log.warn("UserRealm " + getName()
244                       + " could not load user information from database", e);
245             connectDatabase();
246         }
247     }
248 }
249
Popular Tags