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