/* Copyright (c) 2001-2019, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


package org.hsqldb.auth;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Set;

import org.hsqldb.lib.FrameworkLogger;

Delegates authentication decisions, and optionally determination of user roles and schema, to a different HyperSQL catalog, which may be in the same JVM or remote. For now, at least, this class uses DriverManager to make the ephemeral database connections.
Author:Blaine Simpson (blaine dot simpson at admc dot com)
See Also:
  • AuthFunctionBean
Since:2.0.1
/** * Delegates authentication decisions, and optionally determination of user * roles and schema, to a different HyperSQL catalog, which may be in the same * JVM or remote. * * For now, at least, this class uses DriverManager to make the ephemeral * database connections. * * @see AuthFunctionBean * @author Blaine Simpson (blaine dot simpson at admc dot com) * @since 2.0.1 */
public class HsqldbSlaveAuthBean implements AuthFunctionBean { private static FrameworkLogger logger = FrameworkLogger.getLog(HsqldbSlaveAuthBean.class); private String masterJdbcUrl, validationUser, validationPassword; private boolean delegateRolesSchema = true; protected boolean initialized;
Use this method and setValidationPassword if you want access to the master database to be verified upon instance initialization.
/** * Use this method and setValidationPassword if you want access to the * master database to be verified upon instance initialization. */
public void setValidationUser(String validationUser) { this.validationUser = validationUser; }
Use this method and setValidationUser if you want access to the master database to be verified upon instance initialization.
/** * Use this method and setValidationUser if you want access to the * master database to be verified upon instance initialization. */
public void setValidationPassword(String validationPassword) { this.validationPassword = validationPassword; } public void setMasterJdbcUrl(String masterJdbcUrl) { this.masterJdbcUrl = masterJdbcUrl; }
Defaults to true. Whether roles and initial schema for the new session will be determined by what they are for this user in the master database.
/** * Defaults to true. * * Whether roles and initial schema for the new session will be determined * by what they are for this user in the master database. */
public void setDelegateRolesSchema(boolean doDelegateRolesSchema) { delegateRolesSchema = doDelegateRolesSchema; } public HsqldbSlaveAuthBean() { // Intentionally empty }
Throws:
  • IllegalStateException – if any required setting has not been set.
  • SQLException – if properties 'validationUser' and 'validationPassword' have been set, but we fail to connect to the master database.
/** * @throws IllegalStateException if any required setting has not been set. * @throws SQLException if properties 'validationUser' and * 'validationPassword' have been set, but we fail to connect to the * master database. */
public void init() throws SQLException { if (masterJdbcUrl == null) { throw new IllegalStateException( "Required property 'masterJdbcUrl' not set"); } if (validationUser != null || validationPassword != null) { if (validationUser == null || validationPassword == null) { throw new IllegalStateException( "If you set one property of 'validationUser' or " + "'validationPassword', then you must set both."); } Connection c = null; SQLException problem = null; try { c = DriverManager.getConnection( masterJdbcUrl, validationUser, validationPassword); } catch (SQLException se) { logger.error("Master/slave Connection validation failure", se); problem = se; // Just indicates to let the original exception // percolate through in the finally block, to prevent an // exception in the finally block from obscuring the ultimate // cause of the problem. } finally { if (c != null) try { c.close(); c = null; // Encourage GC } catch (SQLException nestedSe) { logger.error( "Failed to close test master/slave Connection", nestedSe); if (problem == null) { throw nestedSe; } } } } initialized = true; }
See Also:
  • authenticate.authenticate(String, String)
/** * @see AuthFunctionBean#authenticate(String, String) */
public String[] authenticate(String userName, String password) throws DenyException { if (!initialized) { throw new IllegalStateException( "You must invoke the 'init' method to initialize the " + HsqldbSlaveAuthBean.class.getName() + " instance."); } Connection c = null; try { c = DriverManager.getConnection(masterJdbcUrl, userName, password); if (delegateRolesSchema) { Set<String> schemaAndRoles = AuthUtils.getEnabledRoles(c); String schemaOnMaster = AuthUtils.getInitialSchema(c); if (schemaOnMaster != null) { schemaAndRoles.add(schemaOnMaster); } logger.finer("Slave delegating schema+roles: " + schemaAndRoles); return schemaAndRoles.toArray(new String[0]); } return null; } catch (SQLException se) { throw new DenyException(); } finally { if (c != null) try { c.close(); c = null; // Encourage GC } catch (SQLException nestedSe) { logger.severe( "Failed to close master/slave Connection", nestedSe); } } } }