103928aee4356845252ac6b662d5c72c29903813eJake Slack//
203928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
303928aee4356845252ac6b662d5c72c29903813eJake Slack//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
403928aee4356845252ac6b662d5c72c29903813eJake Slack//  ------------------------------------------------------------------------
503928aee4356845252ac6b662d5c72c29903813eJake Slack//  All rights reserved. This program and the accompanying materials
603928aee4356845252ac6b662d5c72c29903813eJake Slack//  are made available under the terms of the Eclipse Public License v1.0
703928aee4356845252ac6b662d5c72c29903813eJake Slack//  and Apache License v2.0 which accompanies this distribution.
803928aee4356845252ac6b662d5c72c29903813eJake Slack//
903928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Eclipse Public License is available at
1003928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.eclipse.org/legal/epl-v10.html
1103928aee4356845252ac6b662d5c72c29903813eJake Slack//
1203928aee4356845252ac6b662d5c72c29903813eJake Slack//      The Apache License v2.0 is available at
1303928aee4356845252ac6b662d5c72c29903813eJake Slack//      http://www.opensource.org/licenses/apache2.0.php
1403928aee4356845252ac6b662d5c72c29903813eJake Slack//
1503928aee4356845252ac6b662d5c72c29903813eJake Slack//  You may elect to redistribute this code under either of these licenses.
1603928aee4356845252ac6b662d5c72c29903813eJake Slack//  ========================================================================
1703928aee4356845252ac6b662d5c72c29903813eJake Slack//
1803928aee4356845252ac6b662d5c72c29903813eJake Slack
1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.security;
2003928aee4356845252ac6b662d5c72c29903813eJake Slack
2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException;
2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.Connection;
2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.DriverManager;
2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.PreparedStatement;
2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.ResultSet;
2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.SQLException;
2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.ArrayList;
2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List;
2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Properties;
3003928aee4356845252ac6b662d5c72c29903813eJake Slack
3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.UserIdentity;
3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.Loader;
3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log;
3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger;
3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.resource.Resource;
3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.security.Credential;
3703928aee4356845252ac6b662d5c72c29903813eJake Slack
3803928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------ */
3903928aee4356845252ac6b662d5c72c29903813eJake Slack/**
4003928aee4356845252ac6b662d5c72c29903813eJake Slack * HashMapped User Realm with JDBC as data source. JDBCLoginService extends
4103928aee4356845252ac6b662d5c72c29903813eJake Slack * HashULoginService and adds a method to fetch user information from database.
4203928aee4356845252ac6b662d5c72c29903813eJake Slack * The login() method checks the inherited Map for the user. If the user is not
4303928aee4356845252ac6b662d5c72c29903813eJake Slack * found, it will fetch details from the database and populate the inherited
4403928aee4356845252ac6b662d5c72c29903813eJake Slack * Map. It then calls the superclass login() method to perform the actual
4503928aee4356845252ac6b662d5c72c29903813eJake Slack * authentication. Periodically (controlled by configuration parameter),
4603928aee4356845252ac6b662d5c72c29903813eJake Slack * internal hashes are cleared. Caching can be disabled by setting cache refresh
4703928aee4356845252ac6b662d5c72c29903813eJake Slack * interval to zero. Uses one database connection that is initialized at
4803928aee4356845252ac6b662d5c72c29903813eJake Slack * startup. Reconnect on failures. authenticate() is 'synchronized'.
4903928aee4356845252ac6b662d5c72c29903813eJake Slack *
5003928aee4356845252ac6b662d5c72c29903813eJake Slack * An example properties file for configuration is in
5103928aee4356845252ac6b662d5c72c29903813eJake Slack * $JETTY_HOME/etc/jdbcRealm.properties
5203928aee4356845252ac6b662d5c72c29903813eJake Slack *
5303928aee4356845252ac6b662d5c72c29903813eJake Slack * @version $Id: JDBCLoginService.java 4792 2009-03-18 21:55:52Z gregw $
5403928aee4356845252ac6b662d5c72c29903813eJake Slack *
5503928aee4356845252ac6b662d5c72c29903813eJake Slack *
5603928aee4356845252ac6b662d5c72c29903813eJake Slack *
5703928aee4356845252ac6b662d5c72c29903813eJake Slack *
5803928aee4356845252ac6b662d5c72c29903813eJake Slack */
5903928aee4356845252ac6b662d5c72c29903813eJake Slack
6003928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class JDBCLoginService extends MappedLoginService
6103928aee4356845252ac6b662d5c72c29903813eJake Slack{
6203928aee4356845252ac6b662d5c72c29903813eJake Slack    private static final Logger LOG = Log.getLogger(JDBCLoginService.class);
6303928aee4356845252ac6b662d5c72c29903813eJake Slack
6403928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _config;
6503928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _jdbcDriver;
6603928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _url;
6703928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _userName;
6803928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _password;
6903928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _userTableKey;
7003928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _userTablePasswordField;
7103928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _roleTableRoleField;
7203928aee4356845252ac6b662d5c72c29903813eJake Slack    private int _cacheTime;
7303928aee4356845252ac6b662d5c72c29903813eJake Slack    private long _lastHashPurge;
7403928aee4356845252ac6b662d5c72c29903813eJake Slack    private Connection _con;
7503928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _userSql;
7603928aee4356845252ac6b662d5c72c29903813eJake Slack    private String _roleSql;
7703928aee4356845252ac6b662d5c72c29903813eJake Slack
7803928aee4356845252ac6b662d5c72c29903813eJake Slack
7903928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
8003928aee4356845252ac6b662d5c72c29903813eJake Slack    public JDBCLoginService()
8103928aee4356845252ac6b662d5c72c29903813eJake Slack        throws IOException
8203928aee4356845252ac6b662d5c72c29903813eJake Slack    {
8303928aee4356845252ac6b662d5c72c29903813eJake Slack    }
8403928aee4356845252ac6b662d5c72c29903813eJake Slack
8503928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
8603928aee4356845252ac6b662d5c72c29903813eJake Slack    public JDBCLoginService(String name)
8703928aee4356845252ac6b662d5c72c29903813eJake Slack        throws IOException
8803928aee4356845252ac6b662d5c72c29903813eJake Slack    {
8903928aee4356845252ac6b662d5c72c29903813eJake Slack        setName(name);
9003928aee4356845252ac6b662d5c72c29903813eJake Slack    }
9103928aee4356845252ac6b662d5c72c29903813eJake Slack
9203928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
9303928aee4356845252ac6b662d5c72c29903813eJake Slack    public JDBCLoginService(String name, String config)
9403928aee4356845252ac6b662d5c72c29903813eJake Slack        throws IOException
9503928aee4356845252ac6b662d5c72c29903813eJake Slack    {
9603928aee4356845252ac6b662d5c72c29903813eJake Slack        setName(name);
9703928aee4356845252ac6b662d5c72c29903813eJake Slack        setConfig(config);
9803928aee4356845252ac6b662d5c72c29903813eJake Slack    }
9903928aee4356845252ac6b662d5c72c29903813eJake Slack
10003928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
10103928aee4356845252ac6b662d5c72c29903813eJake Slack    public JDBCLoginService(String name, IdentityService identityService, String config)
10203928aee4356845252ac6b662d5c72c29903813eJake Slack        throws IOException
10303928aee4356845252ac6b662d5c72c29903813eJake Slack    {
10403928aee4356845252ac6b662d5c72c29903813eJake Slack        setName(name);
10503928aee4356845252ac6b662d5c72c29903813eJake Slack        setIdentityService(identityService);
10603928aee4356845252ac6b662d5c72c29903813eJake Slack        setConfig(config);
10703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
10803928aee4356845252ac6b662d5c72c29903813eJake Slack
10903928aee4356845252ac6b662d5c72c29903813eJake Slack
11003928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
11103928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
11203928aee4356845252ac6b662d5c72c29903813eJake Slack     * @see org.eclipse.jetty.security.MappedLoginService#doStart()
11303928aee4356845252ac6b662d5c72c29903813eJake Slack     */
11403928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
11503928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void doStart() throws Exception
11603928aee4356845252ac6b662d5c72c29903813eJake Slack    {
11703928aee4356845252ac6b662d5c72c29903813eJake Slack        Properties properties = new Properties();
11803928aee4356845252ac6b662d5c72c29903813eJake Slack        Resource resource = Resource.newResource(_config);
11903928aee4356845252ac6b662d5c72c29903813eJake Slack        properties.load(resource.getInputStream());
12003928aee4356845252ac6b662d5c72c29903813eJake Slack
12103928aee4356845252ac6b662d5c72c29903813eJake Slack        _jdbcDriver = properties.getProperty("jdbcdriver");
12203928aee4356845252ac6b662d5c72c29903813eJake Slack        _url = properties.getProperty("url");
12303928aee4356845252ac6b662d5c72c29903813eJake Slack        _userName = properties.getProperty("username");
12403928aee4356845252ac6b662d5c72c29903813eJake Slack        _password = properties.getProperty("password");
12503928aee4356845252ac6b662d5c72c29903813eJake Slack        String _userTable = properties.getProperty("usertable");
12603928aee4356845252ac6b662d5c72c29903813eJake Slack        _userTableKey = properties.getProperty("usertablekey");
12703928aee4356845252ac6b662d5c72c29903813eJake Slack        String _userTableUserField = properties.getProperty("usertableuserfield");
12803928aee4356845252ac6b662d5c72c29903813eJake Slack        _userTablePasswordField = properties.getProperty("usertablepasswordfield");
12903928aee4356845252ac6b662d5c72c29903813eJake Slack        String _roleTable = properties.getProperty("roletable");
13003928aee4356845252ac6b662d5c72c29903813eJake Slack        String _roleTableKey = properties.getProperty("roletablekey");
13103928aee4356845252ac6b662d5c72c29903813eJake Slack        _roleTableRoleField = properties.getProperty("roletablerolefield");
13203928aee4356845252ac6b662d5c72c29903813eJake Slack        String _userRoleTable = properties.getProperty("userroletable");
13303928aee4356845252ac6b662d5c72c29903813eJake Slack        String _userRoleTableUserKey = properties.getProperty("userroletableuserkey");
13403928aee4356845252ac6b662d5c72c29903813eJake Slack        String _userRoleTableRoleKey = properties.getProperty("userroletablerolekey");
13503928aee4356845252ac6b662d5c72c29903813eJake Slack        _cacheTime = new Integer(properties.getProperty("cachetime"));
13603928aee4356845252ac6b662d5c72c29903813eJake Slack
13703928aee4356845252ac6b662d5c72c29903813eJake Slack        if (_jdbcDriver == null || _jdbcDriver.equals("")
13803928aee4356845252ac6b662d5c72c29903813eJake Slack            || _url == null
13903928aee4356845252ac6b662d5c72c29903813eJake Slack            || _url.equals("")
14003928aee4356845252ac6b662d5c72c29903813eJake Slack            || _userName == null
14103928aee4356845252ac6b662d5c72c29903813eJake Slack            || _userName.equals("")
14203928aee4356845252ac6b662d5c72c29903813eJake Slack            || _password == null
14303928aee4356845252ac6b662d5c72c29903813eJake Slack            || _cacheTime < 0)
14403928aee4356845252ac6b662d5c72c29903813eJake Slack        {
14503928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn("UserRealm " + getName() + " has not been properly configured");
14603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
14703928aee4356845252ac6b662d5c72c29903813eJake Slack        _cacheTime *= 1000;
14803928aee4356845252ac6b662d5c72c29903813eJake Slack        _lastHashPurge = 0;
14903928aee4356845252ac6b662d5c72c29903813eJake Slack        _userSql = "select " + _userTableKey + "," + _userTablePasswordField + " from " + _userTable + " where " + _userTableUserField + " = ?";
15003928aee4356845252ac6b662d5c72c29903813eJake Slack        _roleSql = "select r." + _roleTableRoleField
15103928aee4356845252ac6b662d5c72c29903813eJake Slack                   + " from "
15203928aee4356845252ac6b662d5c72c29903813eJake Slack                   + _roleTable
15303928aee4356845252ac6b662d5c72c29903813eJake Slack                   + " r, "
15403928aee4356845252ac6b662d5c72c29903813eJake Slack                   + _userRoleTable
15503928aee4356845252ac6b662d5c72c29903813eJake Slack                   + " u where u."
15603928aee4356845252ac6b662d5c72c29903813eJake Slack                   + _userRoleTableUserKey
15703928aee4356845252ac6b662d5c72c29903813eJake Slack                   + " = ?"
15803928aee4356845252ac6b662d5c72c29903813eJake Slack                   + " and r."
15903928aee4356845252ac6b662d5c72c29903813eJake Slack                   + _roleTableKey
16003928aee4356845252ac6b662d5c72c29903813eJake Slack                   + " = u."
16103928aee4356845252ac6b662d5c72c29903813eJake Slack                   + _userRoleTableRoleKey;
16203928aee4356845252ac6b662d5c72c29903813eJake Slack
16303928aee4356845252ac6b662d5c72c29903813eJake Slack        Loader.loadClass(this.getClass(), _jdbcDriver).newInstance();
16403928aee4356845252ac6b662d5c72c29903813eJake Slack        super.doStart();
16503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
16603928aee4356845252ac6b662d5c72c29903813eJake Slack
16703928aee4356845252ac6b662d5c72c29903813eJake Slack
16803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
16903928aee4356845252ac6b662d5c72c29903813eJake Slack    public String getConfig()
17003928aee4356845252ac6b662d5c72c29903813eJake Slack    {
17103928aee4356845252ac6b662d5c72c29903813eJake Slack        return _config;
17203928aee4356845252ac6b662d5c72c29903813eJake Slack    }
17303928aee4356845252ac6b662d5c72c29903813eJake Slack
17403928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
17503928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
17603928aee4356845252ac6b662d5c72c29903813eJake Slack     * Load JDBC connection configuration from properties file.
17703928aee4356845252ac6b662d5c72c29903813eJake Slack     *
17803928aee4356845252ac6b662d5c72c29903813eJake Slack     * @param config Filename or url of user properties file.
17903928aee4356845252ac6b662d5c72c29903813eJake Slack     */
18003928aee4356845252ac6b662d5c72c29903813eJake Slack    public void setConfig(String config)
18103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
18203928aee4356845252ac6b662d5c72c29903813eJake Slack        if (isRunning())
18303928aee4356845252ac6b662d5c72c29903813eJake Slack            throw new IllegalStateException("Running");
18403928aee4356845252ac6b662d5c72c29903813eJake Slack        _config=config;
18503928aee4356845252ac6b662d5c72c29903813eJake Slack    }
18603928aee4356845252ac6b662d5c72c29903813eJake Slack
18703928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
18803928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
18903928aee4356845252ac6b662d5c72c29903813eJake Slack     * (re)Connect to database with parameters setup by loadConfig()
19003928aee4356845252ac6b662d5c72c29903813eJake Slack     */
19103928aee4356845252ac6b662d5c72c29903813eJake Slack    public void connectDatabase()
19203928aee4356845252ac6b662d5c72c29903813eJake Slack    {
19303928aee4356845252ac6b662d5c72c29903813eJake Slack        try
19403928aee4356845252ac6b662d5c72c29903813eJake Slack        {
19503928aee4356845252ac6b662d5c72c29903813eJake Slack            Class.forName(_jdbcDriver);
19603928aee4356845252ac6b662d5c72c29903813eJake Slack            _con = DriverManager.getConnection(_url, _userName, _password);
19703928aee4356845252ac6b662d5c72c29903813eJake Slack        }
19803928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (SQLException e)
19903928aee4356845252ac6b662d5c72c29903813eJake Slack        {
20003928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn("UserRealm " + getName() + " could not connect to database; will try later", e);
20103928aee4356845252ac6b662d5c72c29903813eJake Slack        }
20203928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (ClassNotFoundException e)
20303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
20403928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn("UserRealm " + getName() + " could not connect to database; will try later", e);
20503928aee4356845252ac6b662d5c72c29903813eJake Slack        }
20603928aee4356845252ac6b662d5c72c29903813eJake Slack    }
20703928aee4356845252ac6b662d5c72c29903813eJake Slack
20803928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
20903928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
21003928aee4356845252ac6b662d5c72c29903813eJake Slack    public UserIdentity login(String username, Object credentials)
21103928aee4356845252ac6b662d5c72c29903813eJake Slack    {
21203928aee4356845252ac6b662d5c72c29903813eJake Slack        long now = System.currentTimeMillis();
21303928aee4356845252ac6b662d5c72c29903813eJake Slack        if (now - _lastHashPurge > _cacheTime || _cacheTime == 0)
21403928aee4356845252ac6b662d5c72c29903813eJake Slack        {
21503928aee4356845252ac6b662d5c72c29903813eJake Slack            _users.clear();
21603928aee4356845252ac6b662d5c72c29903813eJake Slack            _lastHashPurge = now;
21703928aee4356845252ac6b662d5c72c29903813eJake Slack            closeConnection();
21803928aee4356845252ac6b662d5c72c29903813eJake Slack        }
21903928aee4356845252ac6b662d5c72c29903813eJake Slack
22003928aee4356845252ac6b662d5c72c29903813eJake Slack        return super.login(username,credentials);
22103928aee4356845252ac6b662d5c72c29903813eJake Slack    }
22203928aee4356845252ac6b662d5c72c29903813eJake Slack
22303928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
22403928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
22503928aee4356845252ac6b662d5c72c29903813eJake Slack    protected void loadUsers()
22603928aee4356845252ac6b662d5c72c29903813eJake Slack    {
22703928aee4356845252ac6b662d5c72c29903813eJake Slack    }
22803928aee4356845252ac6b662d5c72c29903813eJake Slack
22903928aee4356845252ac6b662d5c72c29903813eJake Slack    /* ------------------------------------------------------------ */
23003928aee4356845252ac6b662d5c72c29903813eJake Slack    @Override
23103928aee4356845252ac6b662d5c72c29903813eJake Slack    protected UserIdentity loadUser(String username)
23203928aee4356845252ac6b662d5c72c29903813eJake Slack    {
23303928aee4356845252ac6b662d5c72c29903813eJake Slack        try
23403928aee4356845252ac6b662d5c72c29903813eJake Slack        {
23503928aee4356845252ac6b662d5c72c29903813eJake Slack            if (null == _con)
23603928aee4356845252ac6b662d5c72c29903813eJake Slack                connectDatabase();
23703928aee4356845252ac6b662d5c72c29903813eJake Slack
23803928aee4356845252ac6b662d5c72c29903813eJake Slack            if (null == _con)
23903928aee4356845252ac6b662d5c72c29903813eJake Slack                throw new SQLException("Can't connect to database");
24003928aee4356845252ac6b662d5c72c29903813eJake Slack
24103928aee4356845252ac6b662d5c72c29903813eJake Slack            PreparedStatement stat = _con.prepareStatement(_userSql);
24203928aee4356845252ac6b662d5c72c29903813eJake Slack            stat.setObject(1, username);
24303928aee4356845252ac6b662d5c72c29903813eJake Slack            ResultSet rs = stat.executeQuery();
24403928aee4356845252ac6b662d5c72c29903813eJake Slack
24503928aee4356845252ac6b662d5c72c29903813eJake Slack            if (rs.next())
24603928aee4356845252ac6b662d5c72c29903813eJake Slack            {
24703928aee4356845252ac6b662d5c72c29903813eJake Slack                int key = rs.getInt(_userTableKey);
24803928aee4356845252ac6b662d5c72c29903813eJake Slack                String credentials = rs.getString(_userTablePasswordField);
24903928aee4356845252ac6b662d5c72c29903813eJake Slack                stat.close();
25003928aee4356845252ac6b662d5c72c29903813eJake Slack
25103928aee4356845252ac6b662d5c72c29903813eJake Slack                stat = _con.prepareStatement(_roleSql);
25203928aee4356845252ac6b662d5c72c29903813eJake Slack                stat.setInt(1, key);
25303928aee4356845252ac6b662d5c72c29903813eJake Slack                rs = stat.executeQuery();
25403928aee4356845252ac6b662d5c72c29903813eJake Slack                List<String> roles = new ArrayList<String>();
25503928aee4356845252ac6b662d5c72c29903813eJake Slack                while (rs.next())
25603928aee4356845252ac6b662d5c72c29903813eJake Slack                    roles.add(rs.getString(_roleTableRoleField));
25703928aee4356845252ac6b662d5c72c29903813eJake Slack
25803928aee4356845252ac6b662d5c72c29903813eJake Slack                stat.close();
25903928aee4356845252ac6b662d5c72c29903813eJake Slack                return putUser(username, Credential.getCredential(credentials),roles.toArray(new String[roles.size()]));
26003928aee4356845252ac6b662d5c72c29903813eJake Slack            }
26103928aee4356845252ac6b662d5c72c29903813eJake Slack        }
26203928aee4356845252ac6b662d5c72c29903813eJake Slack        catch (SQLException e)
26303928aee4356845252ac6b662d5c72c29903813eJake Slack        {
26403928aee4356845252ac6b662d5c72c29903813eJake Slack            LOG.warn("UserRealm " + getName() + " could not load user information from database", e);
26503928aee4356845252ac6b662d5c72c29903813eJake Slack            closeConnection();
26603928aee4356845252ac6b662d5c72c29903813eJake Slack        }
26703928aee4356845252ac6b662d5c72c29903813eJake Slack        return null;
26803928aee4356845252ac6b662d5c72c29903813eJake Slack    }
26903928aee4356845252ac6b662d5c72c29903813eJake Slack
27003928aee4356845252ac6b662d5c72c29903813eJake Slack    /**
27103928aee4356845252ac6b662d5c72c29903813eJake Slack     * Close an existing connection
27203928aee4356845252ac6b662d5c72c29903813eJake Slack     */
27303928aee4356845252ac6b662d5c72c29903813eJake Slack    private void closeConnection ()
27403928aee4356845252ac6b662d5c72c29903813eJake Slack    {
27503928aee4356845252ac6b662d5c72c29903813eJake Slack        if (_con != null)
27603928aee4356845252ac6b662d5c72c29903813eJake Slack        {
27703928aee4356845252ac6b662d5c72c29903813eJake Slack            if (LOG.isDebugEnabled()) LOG.debug("Closing db connection for JDBCUserRealm");
27803928aee4356845252ac6b662d5c72c29903813eJake Slack            try { _con.close(); }catch (Exception e) {LOG.ignore(e);}
27903928aee4356845252ac6b662d5c72c29903813eJake Slack        }
28003928aee4356845252ac6b662d5c72c29903813eJake Slack        _con = null;
28103928aee4356845252ac6b662d5c72c29903813eJake Slack    }
28203928aee4356845252ac6b662d5c72c29903813eJake Slack
28303928aee4356845252ac6b662d5c72c29903813eJake Slack}
284