001 /* 002 * $Id: JDBCLoginService.java,v 1.6 2005/11/11 23:05:15 rbair Exp $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 package org.jdesktop.swingx.auth; 022 import java.sql.Connection; 023 import java.sql.DriverManager; 024 import java.util.Properties; 025 import java.util.logging.Level; 026 import java.util.logging.Logger; 027 028 import javax.naming.InitialContext; 029 /** 030 * A login service for connecting to SQL based databases via JDBC 031 * 032 * @author rbair 033 */ 034 public class JDBCLoginService extends LoginService { 035 private static final Logger LOG = Logger.getLogger(JDBCLoginService.class 036 .getName()); 037 038 /** 039 * The connection to the database 040 */ 041 private Connection conn; 042 /** 043 * If used, defines the JNDI context from which to get a connection to 044 * the data base 045 */ 046 private String jndiContext; 047 /** 048 * When using the DriverManager to connect to the database, this specifies 049 * any additional properties to use when connecting. 050 */ 051 private Properties properties; 052 053 /** 054 * Create a new JDBCLoginService and initializes it to connect to a 055 * database using the given params. 056 * @param driver 057 * @param url 058 */ 059 public JDBCLoginService(String driver, String url) { 060 super(url); 061 try { 062 Class.forName(driver); 063 } catch (Exception e) { 064 LOG.log(Level.WARNING, "The driver passed to the " + 065 "JDBCLoginService constructor could not be loaded. " + 066 "This may be due to the driver not being on the classpath", e); 067 } 068 this.setUrl(url); 069 } 070 071 /** 072 * Create a new JDBCLoginService and initializes it to connect to a 073 * database using the given params. 074 * @param driver 075 * @param url 076 * @param props 077 */ 078 public JDBCLoginService(String driver, String url, Properties props) { 079 super(url); 080 try { 081 Class.forName(driver); 082 } catch (Exception e) { 083 LOG.log(Level.WARNING, "The driver passed to the " + 084 "JDBCLoginService constructor could not be loaded. " + 085 "This may be due to the driver not being on the classpath", e); 086 } 087 this.setUrl(url); 088 this.setProperties(props); 089 } 090 091 /** 092 * Create a new JDBCLoginService and initializes it to connect to a 093 * database using the given params. 094 * @param jndiContext 095 */ 096 public JDBCLoginService(String jndiContext) { 097 super(jndiContext); 098 this.jndiContext = jndiContext; 099 } 100 101 /** 102 * @return the JDBC connection url 103 */ 104 public String getUrl() { 105 return getServer(); 106 } 107 108 /** 109 * @param url set the JDBC connection url 110 */ 111 public void setUrl(String url) { 112 setServer(url); 113 } 114 115 /** 116 * @return JDBC connection properties 117 */ 118 public Properties getProperties() { 119 return properties; 120 } 121 122 /** 123 * @param properties miscellaneous JDBC properties to use when connecting 124 * to the database via the JDBC driver 125 */ 126 public void setProperties(Properties properties) { 127 this.properties = properties; 128 } 129 130 public Connection getConnection() { 131 return conn; 132 } 133 134 /** 135 * Attempts to get a JDBC Connection from a JNDI javax.sql.DataSource, using 136 * that connection for interacting with the database. 137 * @throws Exception 138 */ 139 private void connectByJNDI(String userName, char[] password) throws Exception { 140 InitialContext ctx = new InitialContext(); 141 javax.sql.DataSource ds = (javax.sql.DataSource)ctx.lookup(jndiContext); 142 conn = ds.getConnection(userName, new String(password)); 143 conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 144 } 145 146 /** 147 * Attempts to get a JDBC Connection from a DriverManager. If properties 148 * is not null, it tries to connect with those properties. If that fails, 149 * it then attempts to connect with a user name and password. If that fails, 150 * it attempts to connect without any credentials at all. 151 * <p> 152 * If, on the other hand, properties is null, it first attempts to connect 153 * with a username and password. Failing that, it tries to connect without 154 * any credentials at all. 155 * @throws Exception 156 */ 157 private void connectByDriverManager(String userName, char[] password) throws Exception { 158 if (getProperties() != null) { 159 try { 160 conn = DriverManager.getConnection(getUrl(), getProperties()); 161 conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 162 } catch (Exception e) { 163 try { 164 conn = DriverManager.getConnection(getUrl(), userName, new String(password)); 165 conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 166 } catch (Exception ex) { 167 conn = DriverManager.getConnection(getUrl()); 168 conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 169 } 170 } 171 } else { 172 try { 173 conn = DriverManager.getConnection(getUrl(), userName, new String(password)); 174 } catch (Exception e) { 175 LOG.log(Level.WARNING, "Connection with properties failed. " + 176 "Tryint to connect without.", e); 177 //try to connect without using the userName and password 178 conn = DriverManager.getConnection(getUrl()); 179 180 } 181 } 182 } 183 184 /** 185 * @param name user name 186 * @param password user password 187 * @param server Must be either a valid JDBC URL for the type of JDBC driver you are using, 188 * or must be a valid JNDIContext from which to get the database connection 189 */ 190 public boolean authenticate(String name, char[] password, String server) throws Exception { 191 //try to form a connection. If it works, conn will not be null 192 //if the jndiContext is not null, then try to get the DataSource to use 193 //from jndi 194 if (jndiContext != null) { 195 try { 196 connectByJNDI(name, password); 197 } catch (Exception e) { 198 try { 199 connectByDriverManager(name, password); 200 } catch (Exception ex) { 201 LOG.log(Level.WARNING, "Login failed", ex); 202 //login failed 203 return false; 204 } 205 } 206 } else { 207 try { 208 connectByDriverManager(name, password); 209 } catch (Exception ex) { 210 LOG.log(Level.WARNING, "", ex); 211 return false; 212 } 213 } 214 return true; 215 } 216 }