java/sql-java-prihlasovani/src/cz/frantovo/jaas/sql/SQLRealm.java
author František Kučera <franta-hg@frantovo.cz>
Tue, 07 Feb 2012 00:27:39 +0100
changeset 6 aff44e80f418
parent 4 c7d713d71ad3
child 7 46bb283a674d
permissions -rw-r--r--
Napojení na SQL databázi.
franta-hg@2
     1
package cz.frantovo.jaas.sql;
franta-hg@2
     2
franta-hg@2
     3
import com.sun.appserv.security.AppservRealm;
franta-hg@4
     4
import com.sun.enterprise.security.auth.realm.BadRealmException;
franta-hg@4
     5
import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
franta-hg@2
     6
import com.sun.enterprise.security.auth.realm.NoSuchUserException;
franta-hg@6
     7
import java.sql.Connection;
franta-hg@6
     8
import java.sql.PreparedStatement;
franta-hg@6
     9
import java.sql.ResultSet;
franta-hg@6
    10
import java.sql.SQLException;
franta-hg@6
    11
import java.sql.Statement;
franta-hg@6
    12
import java.util.ArrayList;
franta-hg@6
    13
import java.util.Collection;
franta-hg@6
    14
import java.util.Collections;
franta-hg@2
    15
import java.util.Enumeration;
franta-hg@4
    16
import java.util.Properties;
franta-hg@4
    17
import java.util.logging.Level;
franta-hg@6
    18
import javax.naming.InitialContext;
franta-hg@6
    19
import javax.naming.NamingException;
franta-hg@4
    20
import javax.security.auth.login.LoginException;
franta-hg@6
    21
import javax.sql.DataSource;
franta-hg@2
    22
franta-hg@2
    23
/**
franta-hg@6
    24
 * Bezpečnostní doména. Uživatelé jsou uloženi v SQL databázi.
franta-hg@6
    25
 *
franta-hg@2
    26
 * @author fiki
franta-hg@2
    27
 */
franta-hg@2
    28
public class SQLRealm extends AppservRealm {
franta-hg@2
    29
franta-hg@4
    30
	private static final String AUTH_TYPE = "Ověřuje uživatele proti SQL databázi.";
franta-hg@6
    31
	private static final String PARAM_JNDI = "jndi";
franta-hg@6
    32
	private static final String PARAM_SQL_HESLO = "sql_heslo";
franta-hg@6
    33
	private static final String PARAM_SQL_SKUPINY_UŽIVATELE = "sql_skupiny_uzivatele";
franta-hg@6
    34
	private static final String PARAM_SQL_SKUPINY_VŠECHNY = "sql_skupiny_vsechny";
franta-hg@6
    35
	private DataSource datovýZdroj;
franta-hg@6
    36
	private String sqlHeslo;
franta-hg@6
    37
	private String sqlSkupinyUživatele;
franta-hg@6
    38
	private String sqlSkupinyVšechny;
franta-hg@4
    39
franta-hg@6
    40
	/**
franta-hg@6
    41
	 * Načteme a zkontrolujeme parametry
franta-hg@6
    42
	 *
franta-hg@6
    43
	 * @param parametry
franta-hg@6
    44
	 * @throws BadRealmException pokud je v parametrech chyba
franta-hg@6
    45
	 * @throws NoSuchRealmException
franta-hg@6
    46
	 */
franta-hg@2
    47
	@Override
franta-hg@4
    48
	public void init(Properties parametry) throws BadRealmException, NoSuchRealmException {
franta-hg@4
    49
		super.init(parametry);
franta-hg@4
    50
franta-hg@4
    51
		String jaasContext = parametry.getProperty(JAAS_CONTEXT_PARAM, SQLLoginModul.VÝCHOZÍ_JAAS_KONTEXT);
franta-hg@4
    52
		setProperty(JAAS_CONTEXT_PARAM, jaasContext);
franta-hg@4
    53
franta-hg@6
    54
		/** Databázové spojení */
franta-hg@6
    55
		{
franta-hg@6
    56
			String jndi = najdiParametr(parametry, PARAM_JNDI, "název datového zdroje");
franta-hg@6
    57
			try {
franta-hg@6
    58
				InitialContext k = new InitialContext();
franta-hg@6
    59
				jndi = parametry.getProperty(PARAM_JNDI);
franta-hg@6
    60
				datovýZdroj = (DataSource) k.lookup(jndi);
franta-hg@6
    61
			} catch (NamingException e) {
franta-hg@6
    62
				throw new BadRealmException("Datový zdroj s tímto názvem nebyl nalezen: " + jndi, e);
franta-hg@6
    63
			}
franta-hg@6
    64
		}
franta-hg@6
    65
franta-hg@6
    66
		/** SQL dotazy */
franta-hg@6
    67
		sqlHeslo = najdiParametr(parametry, PARAM_SQL_HESLO, "SQL dotaz pro ověření jména a hesla");
franta-hg@6
    68
		sqlSkupinyUživatele = najdiParametr(parametry, PARAM_SQL_SKUPINY_UŽIVATELE, "SQL dotaz pro zjištění skupin uživatele");
franta-hg@6
    69
		sqlSkupinyVšechny = najdiParametr(parametry, PARAM_SQL_SKUPINY_VŠECHNY, "SQL dotaz pro zjištění všech skupin");
franta-hg@6
    70
franta-hg@6
    71
		_logger.log(Level.INFO, "SQLRealm úspěšně vytvořen. JaasContext: {0}", jaasContext);
franta-hg@2
    72
	}
franta-hg@6
    73
	
franta-hg@2
    74
	@Override
franta-hg@4
    75
	public String getAuthType() {
franta-hg@4
    76
		return AUTH_TYPE;
franta-hg@4
    77
	}
franta-hg@4
    78
franta-hg@4
    79
	/**
franta-hg@4
    80
	 * @param uživatel přihlašovací jméno uživatele
franta-hg@4
    81
	 * @return seznam skupin, ve kterých se daný uživatel nachází
franta-hg@4
    82
	 * @throws NoSuchUserException když uživatel s tímto jménem neexistuje.
franta-hg@4
    83
	 */
franta-hg@4
    84
	@Override
franta-hg@6
    85
	public Enumeration<String> getGroupNames(String uživatel) throws NoSuchUserException {
franta-hg@6
    86
		Collection<String> skupiny = new ArrayList<>();
franta-hg@6
    87
franta-hg@6
    88
		Connection s = null;
franta-hg@6
    89
		PreparedStatement ps = null;
franta-hg@6
    90
		ResultSet rs = null;
franta-hg@6
    91
		try {
franta-hg@6
    92
			s = datovýZdroj.getConnection();
franta-hg@6
    93
			ps = s.prepareStatement(sqlSkupinyUživatele);
franta-hg@6
    94
			ps.setString(1, uživatel);
franta-hg@6
    95
			rs = ps.executeQuery();
franta-hg@6
    96
franta-hg@6
    97
			while (rs.next()) {
franta-hg@6
    98
				skupiny.add(rs.getString(1));
franta-hg@6
    99
			}
franta-hg@6
   100
franta-hg@6
   101
			return Collections.enumeration(skupiny);
franta-hg@6
   102
franta-hg@6
   103
		} catch (Exception e) {
franta-hg@6
   104
			String hláška = "Chyba při zjišťování skupin uživatele: " + uživatel + ".";
franta-hg@6
   105
			_logger.log(Level.WARNING, hláška, e);
franta-hg@6
   106
			throw new NoSuchUserException(hláška);
franta-hg@6
   107
		} finally {
franta-hg@6
   108
			zavri(s, ps, rs);
franta-hg@6
   109
		}
franta-hg@4
   110
	}
franta-hg@4
   111
franta-hg@4
   112
	/**
franta-hg@4
   113
	 * 
franta-hg@4
   114
	 * @param jméno uživatelské jméno
franta-hg@4
   115
	 * @param heslo heslo
franta-hg@6
   116
	 * @return true pokud je jméno a heslo v pořádku | false nikdy – vyhazuje výjimku
franta-hg@6
   117
	 * @throws LoginException pokud je jméno nebo heslo neplatné nebo došlo k jiné chybě
franta-hg@4
   118
	 */
franta-hg@6
   119
	public boolean ověřUživatele(String jméno, char[] heslo) throws LoginException {
franta-hg@4
   120
franta-hg@6
   121
		Connection s = null;
franta-hg@6
   122
		PreparedStatement ps = null;
franta-hg@6
   123
		ResultSet rs = null;
franta-hg@6
   124
		try {
franta-hg@6
   125
			s = datovýZdroj.getConnection();
franta-hg@6
   126
			ps = s.prepareStatement(sqlHeslo);
franta-hg@6
   127
			ps.setString(1, jméno);
franta-hg@6
   128
			ps.setString(2, new String(heslo));
franta-hg@6
   129
			rs = ps.executeQuery();
franta-hg@4
   130
franta-hg@6
   131
			if (rs.next()) {
franta-hg@6
   132
				String dbJméno = rs.getString(1);
franta-hg@6
   133
				if (dbJméno.equals(jméno)) {
franta-hg@6
   134
					// OK – úspěšné ověření
franta-hg@6
   135
					return true;
franta-hg@6
   136
				} else {
franta-hg@6
   137
					throw new LoginException("Nebyl nalezen správný uživatel: " + jméno + " != " + dbJméno);
franta-hg@6
   138
				}
franta-hg@6
   139
			} else {
franta-hg@6
   140
				throw new LoginException("Uživatel nebyl nalezen: " + jméno);
franta-hg@6
   141
			}
franta-hg@6
   142
		} catch (SQLException e) {
franta-hg@6
   143
			String hláška = "SQL chyba při ověřování hesla uživatele: " + jméno + ".";
franta-hg@6
   144
			_logger.log(Level.WARNING, hláška, e);
franta-hg@6
   145
			throw new LoginException(hláška);
franta-hg@6
   146
		} finally {
franta-hg@6
   147
			zavri(s, ps, rs);
franta-hg@6
   148
		}
franta-hg@6
   149
	}
franta-hg@6
   150
franta-hg@6
   151
	private String najdiParametr(Properties parametry, String názevParametru, String popis) throws BadRealmException {
franta-hg@6
   152
		String hodnotaParametru = parametry.getProperty(názevParametru);
franta-hg@6
   153
franta-hg@6
   154
		if (hodnotaParametru == null || hodnotaParametru.length() < 1) {
franta-hg@6
   155
			throw new BadRealmException("Chybí " + popis + " – parametr: " + názevParametru);
franta-hg@4
   156
		} else {
franta-hg@6
   157
			return hodnotaParametru;
franta-hg@6
   158
		}
franta-hg@6
   159
	}
franta-hg@6
   160
franta-hg@6
   161
	/**
franta-hg@6
   162
	 * Zavře všechno
franta-hg@6
   163
	 *
franta-hg@6
   164
	 * @param spojeni DB spojení
franta-hg@6
   165
	 * @param prikaz DB dotaz
franta-hg@6
   166
	 * @param vysledek DB výsledek
franta-hg@6
   167
	 */
franta-hg@6
   168
	private static void zavri(Connection spojeni, Statement prikaz, ResultSet vysledek) {
franta-hg@6
   169
		if (vysledek != null) {
franta-hg@6
   170
			try {
franta-hg@6
   171
				vysledek.close();
franta-hg@6
   172
			} catch (Exception e) {
franta-hg@6
   173
			}
franta-hg@6
   174
		}
franta-hg@6
   175
		if (prikaz != null) {
franta-hg@6
   176
			try {
franta-hg@6
   177
				prikaz.close();
franta-hg@6
   178
			} catch (Exception e) {
franta-hg@6
   179
			}
franta-hg@6
   180
		}
franta-hg@6
   181
		if (spojeni != null) {
franta-hg@6
   182
			try {
franta-hg@6
   183
				spojeni.close();
franta-hg@6
   184
			} catch (Exception e) {
franta-hg@6
   185
			}
franta-hg@4
   186
		}
franta-hg@2
   187
	}
franta-hg@2
   188
}