Napojení na SQL databázi.
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 07 Feb 2012 00:27:39 +0100
changeset 6aff44e80f418
parent 5 e013564c8e6f
child 7 46bb283a674d
Napojení na SQL databázi.
analýza/jaas.txt
java/sql-java-prihlasovani/nbproject/build-impl.xml
java/sql-java-prihlasovani/nbproject/genfiles.properties
java/sql-java-prihlasovani/nbproject/project.properties
java/sql-java-prihlasovani/src/cz/frantovo/jaas/sql/SQLLoginModul.java
java/sql-java-prihlasovani/src/cz/frantovo/jaas/sql/SQLRealm.java
java/sql-java-prihlasovani/test/cz/frantovo/jaas/sql/SQLRealmTest.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/analýza/jaas.txt	Tue Feb 07 00:27:39 2012 +0100
     1.3 @@ -0,0 +1,26 @@
     1.4 +Java – Glassfish – JAAS
     1.5 +-----------------------
     1.6 +
     1.7 +Důležité pojmy:
     1.8 +	- Realm – vytváří se jen jednou, obsahuje parametry (Properties)
     1.9 +	- Login modul – vytváří se při každém pokusu o přihlášení
    1.10 +
    1.11 +		----------------------------------
    1.12 +		Uživatel ← → Login modul ← → Realm
    1.13 +		----------------------------------
    1.14 +
    1.15 +V konfiguraci Glassfishe definujeme ověřování uživatelů jako Realm, ke kterému zadáme JAAS Context.
    1.16 +Nemůžeme tam zadat cokoli, musí to být hodnota z login.conf – podle ní se totiž dohledá příslušný Login modul.
    1.17 +
    1.18 +Viz konfigurace/glassfish/login.conf
    1.19 +
    1.20 +Knihovnu sql-java-prihlasovani.jar musíme dát do /opt/glassfish3/glassfish/lib/
    1.21 +ne do /opt/glassfish3/glassfish/domains/domain1/lib/ext/
    1.22 +Jinak bychom totiž dostali tuto chybu:
    1.23 +
    1.24 +--------------------------------------------------------------------------------
    1.25 +[#|2012-02-06T20:04:34.502+0100|SEVERE|glassfish3.1.1|javax.enterprise.system.tools.admin.com.sun.enterprise.v3.admin|_ThreadID=109;_ThreadName=Thread-2;|Exception in command execu
    1.26 +tion : java.lang.NoClassDefFoundError: com/sun/appserv/security/AppservRealm
    1.27 +java.lang.NoClassDefFoundError: com/sun/appserv/security/AppservRealm
    1.28 +…
    1.29 +--------------------------------------------------------------------------------
     2.1 --- a/java/sql-java-prihlasovani/nbproject/build-impl.xml	Thu Jul 21 23:41:05 2011 +0200
     2.2 +++ b/java/sql-java-prihlasovani/nbproject/build-impl.xml	Tue Feb 07 00:27:39 2012 +0100
     2.3 @@ -20,10 +20,10 @@
     2.4  
     2.5          -->
     2.6  <project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="sql-java-prihlasovani-impl">
     2.7 -    <fail message="Please build using Ant 1.7.1 or higher.">
     2.8 +    <fail message="Please build using Ant 1.8.0 or higher.">
     2.9          <condition>
    2.10              <not>
    2.11 -                <antversion atleast="1.7.1"/>
    2.12 +                <antversion atleast="1.8.0"/>
    2.13              </not>
    2.14          </condition>
    2.15      </fail>
    2.16 @@ -198,6 +198,7 @@
    2.17          <property name="javac.fork" value="${jdkBug6558476}"/>
    2.18          <property name="jar.index" value="false"/>
    2.19          <property name="jar.index.metainf" value="${jar.index}"/>
    2.20 +        <property name="copylibs.rebase" value="true"/>
    2.21          <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
    2.22      </target>
    2.23      <target name="-post-init">
    2.24 @@ -384,6 +385,7 @@
    2.25                  <property environment="env"/>
    2.26                  <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
    2.27                  <java classname="@{classname}" dir="${profiler.info.dir}" fork="true" jvm="${profiler.info.jvm}">
    2.28 +                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
    2.29                      <jvmarg value="${profiler.info.jvmargs.agent}"/>
    2.30                      <jvmarg line="${profiler.info.jvmargs}"/>
    2.31                      <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
    2.32 @@ -514,7 +516,7 @@
    2.33                      </chainedmapper>
    2.34                  </pathconvert>
    2.35                  <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
    2.36 -                <copylibs compress="${jar.compress}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
    2.37 +                <copylibs compress="${jar.compress}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
    2.38                      <fileset dir="${build.classes.dir}"/>
    2.39                      <manifest>
    2.40                          <attribute name="Class-Path" value="${jar.classpath}"/>
    2.41 @@ -839,16 +841,26 @@
    2.42              -->
    2.43      <target depends="init" if="have.sources" name="-javadoc-build">
    2.44          <mkdir dir="${dist.javadoc.dir}"/>
    2.45 +        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
    2.46 +            <and>
    2.47 +                <isset property="endorsed.classpath.cmd.line.arg"/>
    2.48 +                <not>
    2.49 +                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
    2.50 +                </not>
    2.51 +            </and>
    2.52 +        </condition>
    2.53          <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
    2.54              <classpath>
    2.55                  <path path="${javac.classpath}"/>
    2.56              </classpath>
    2.57 -            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
    2.58 +            <fileset dir="${src.dir}" excludes="*.java,${excludes}" includes="${includes}">
    2.59                  <filename name="**/*.java"/>
    2.60              </fileset>
    2.61              <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
    2.62                  <include name="**/*.java"/>
    2.63 +                <exclude name="*.java"/>
    2.64              </fileset>
    2.65 +            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
    2.66          </javadoc>
    2.67          <copy todir="${dist.javadoc.dir}">
    2.68              <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
     3.1 --- a/java/sql-java-prihlasovani/nbproject/genfiles.properties	Thu Jul 21 23:41:05 2011 +0200
     3.2 +++ b/java/sql-java-prihlasovani/nbproject/genfiles.properties	Tue Feb 07 00:27:39 2012 +0100
     3.3 @@ -4,5 +4,5 @@
     3.4  # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
     3.5  # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
     3.6  nbproject/build-impl.xml.data.CRC32=916fc21a
     3.7 -nbproject/build-impl.xml.script.CRC32=7e41f0b2
     3.8 -nbproject/build-impl.xml.stylesheet.CRC32=0c01fd8e@1.43.1.45
     3.9 +nbproject/build-impl.xml.script.CRC32=2d24efe9
    3.10 +nbproject/build-impl.xml.stylesheet.CRC32=fcddb364@1.50.1.46
     4.1 --- a/java/sql-java-prihlasovani/nbproject/project.properties	Thu Jul 21 23:41:05 2011 +0200
     4.2 +++ b/java/sql-java-prihlasovani/nbproject/project.properties	Tue Feb 07 00:27:39 2012 +0100
     4.3 @@ -1,9 +1,10 @@
     4.4  annotation.processing.enabled=true
     4.5  annotation.processing.enabled.in.editor=false
     4.6 -annotation.processing.processor.options=
     4.7  annotation.processing.processors.list=
     4.8  annotation.processing.run.all.processors=true
     4.9  annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
    4.10 +application.title=sql-java-prihlasovani
    4.11 +application.vendor=fiki
    4.12  build.classes.dir=${build.dir}/classes
    4.13  build.classes.excludes=**/*.java,**/*.form
    4.14  # This directory is removed when the project is cleaned:
    4.15 @@ -24,6 +25,7 @@
    4.16  dist.dir=dist
    4.17  dist.jar=${dist.dir}/sql-java-prihlasovani.jar
    4.18  dist.javadoc.dir=${dist.dir}/javadoc
    4.19 +endorsed.classpath=
    4.20  excludes=
    4.21  includes=**
    4.22  jar.compress=false
    4.23 @@ -34,8 +36,8 @@
    4.24  javac.deprecation=false
    4.25  javac.processorpath=\
    4.26      ${javac.classpath}
    4.27 -javac.source=1.6
    4.28 -javac.target=1.6
    4.29 +javac.source=1.7
    4.30 +javac.target=1.7
    4.31  javac.test.classpath=\
    4.32      ${javac.classpath}:\
    4.33      ${build.classes.dir}:\
     5.1 --- a/java/sql-java-prihlasovani/src/cz/frantovo/jaas/sql/SQLLoginModul.java	Thu Jul 21 23:41:05 2011 +0200
     5.2 +++ b/java/sql-java-prihlasovani/src/cz/frantovo/jaas/sql/SQLLoginModul.java	Tue Feb 07 00:27:39 2012 +0100
     5.3 @@ -1,33 +1,58 @@
     5.4  package cz.frantovo.jaas.sql;
     5.5  
     5.6  import com.sun.appserv.security.AppservPasswordLoginModule;
     5.7 +import com.sun.enterprise.security.auth.realm.NoSuchUserException;
     5.8 +import java.util.ArrayList;
     5.9  import java.util.Arrays;
    5.10 +import java.util.Enumeration;
    5.11 +import java.util.List;
    5.12  import java.util.logging.Level;
    5.13  import java.util.logging.Logger;
    5.14  import javax.security.auth.login.LoginException;
    5.15  
    5.16  /**
    5.17   * Přihlašovací modul pro SQL doménu.
    5.18 - * TODO: později bude potomkem <code>com.sun.appserv.security.AbstractLoginModule</code>
    5.19 + *
    5.20 + * TODO: později bude potomkem
    5.21 + * <code>com.sun.appserv.security.AbstractLoginModule</code>
    5.22 + *
    5.23   * @author fiki
    5.24   */
    5.25  public class SQLLoginModul extends AppservPasswordLoginModule {
    5.26  
    5.27 -	/** viz konfigurace v login.conf */
    5.28 +	/**
    5.29 +	 * viz konfigurace v login.conf
    5.30 +	 */
    5.31  	public static final String VÝCHOZÍ_JAAS_KONTEXT = "sqlRealm";
    5.32  	private static final Logger log = Logger.getLogger(SQLLoginModul.class.getName());
    5.33  
    5.34  	@Override
    5.35  	protected void authenticateUser() throws LoginException {
    5.36 -
    5.37 -		if (_currentRealm instanceof SQLRealm) {			
    5.38 -		
    5.39 -			SQLRealm sqlRealm = (SQLRealm)_currentRealm;			
    5.40 -			String skupiny[] = sqlRealm.ověřUživatele(_username, _passwd);			
    5.41 -			commitUserAuthentication(skupiny);
    5.42 -			
    5.43 +		if (_currentRealm instanceof SQLRealm) {
    5.44 +			try {
    5.45 +				SQLRealm sqlRealm = (SQLRealm) _currentRealm;
    5.46 +				sqlRealm.ověřUživatele(_username, _passwd);
    5.47 +								
    5.48 +				String skupiny[] = poleSkupin(sqlRealm.getGroupNames(_username));
    5.49 +				log.log(Level.INFO, "Uživatel {0} byl úspěšně ověřen a je členem těchto skupin: {1}", new Object[]{_username, Arrays.toString(skupiny)});
    5.50 +				commitUserAuthentication(skupiny);
    5.51 +			} catch (NoSuchUserException nue) {
    5.52 +				log.log(Level.SEVERE, "Uživatele se podařilo ověřit, ale při pokusu o zjištění jeho skupin došlo k chybě. Uživatel: " + _username, nue);
    5.53 +				throw new LoginException("Neexistující uživatel: " + _username);
    5.54 +			}
    5.55  		} else {
    5.56  			throw new LoginException("Špatný realm: " + _currentRealm + " Očekávám: SQLRealm.");
    5.57  		}
    5.58  	}
    5.59 +	
    5.60 +	/**
    5.61 +	 * Převede výčet na pole
    5.62 +	 */
    5.63 +	private static String[] poleSkupin(Enumeration<String> e) {
    5.64 +		List<String> l = new ArrayList<>();
    5.65 +		while (e.hasMoreElements()) {
    5.66 +			l.add(e.nextElement());
    5.67 +		}
    5.68 +		return l.toArray(new String[0]);
    5.69 +	}
    5.70  }
     6.1 --- a/java/sql-java-prihlasovani/src/cz/frantovo/jaas/sql/SQLRealm.java	Thu Jul 21 23:41:05 2011 +0200
     6.2 +++ b/java/sql-java-prihlasovani/src/cz/frantovo/jaas/sql/SQLRealm.java	Tue Feb 07 00:27:39 2012 +0100
     6.3 @@ -4,22 +4,46 @@
     6.4  import com.sun.enterprise.security.auth.realm.BadRealmException;
     6.5  import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
     6.6  import com.sun.enterprise.security.auth.realm.NoSuchUserException;
     6.7 +import java.sql.Connection;
     6.8 +import java.sql.PreparedStatement;
     6.9 +import java.sql.ResultSet;
    6.10 +import java.sql.SQLException;
    6.11 +import java.sql.Statement;
    6.12 +import java.util.ArrayList;
    6.13 +import java.util.Collection;
    6.14 +import java.util.Collections;
    6.15  import java.util.Enumeration;
    6.16  import java.util.Properties;
    6.17  import java.util.logging.Level;
    6.18 -import java.util.logging.Logger;
    6.19 +import javax.naming.InitialContext;
    6.20 +import javax.naming.NamingException;
    6.21  import javax.security.auth.login.LoginException;
    6.22 +import javax.sql.DataSource;
    6.23  
    6.24  /**
    6.25 - * Bezpečnostní doména. 
    6.26 - * Uživatelé jsou uloženi v SQL databázi.
    6.27 + * Bezpečnostní doména. Uživatelé jsou uloženi v SQL databázi.
    6.28 + *
    6.29   * @author fiki
    6.30   */
    6.31  public class SQLRealm extends AppservRealm {
    6.32  
    6.33  	private static final String AUTH_TYPE = "Ověřuje uživatele proti SQL databázi.";
    6.34 -	private static final Logger log = Logger.getLogger(SQLRealm.class.getName());
    6.35 +	private static final String PARAM_JNDI = "jndi";
    6.36 +	private static final String PARAM_SQL_HESLO = "sql_heslo";
    6.37 +	private static final String PARAM_SQL_SKUPINY_UŽIVATELE = "sql_skupiny_uzivatele";
    6.38 +	private static final String PARAM_SQL_SKUPINY_VŠECHNY = "sql_skupiny_vsechny";
    6.39 +	private DataSource datovýZdroj;
    6.40 +	private String sqlHeslo;
    6.41 +	private String sqlSkupinyUživatele;
    6.42 +	private String sqlSkupinyVšechny;
    6.43  
    6.44 +	/**
    6.45 +	 * Načteme a zkontrolujeme parametry
    6.46 +	 *
    6.47 +	 * @param parametry
    6.48 +	 * @throws BadRealmException pokud je v parametrech chyba
    6.49 +	 * @throws NoSuchRealmException
    6.50 +	 */
    6.51  	@Override
    6.52  	public void init(Properties parametry) throws BadRealmException, NoSuchRealmException {
    6.53  		super.init(parametry);
    6.54 @@ -27,9 +51,26 @@
    6.55  		String jaasContext = parametry.getProperty(JAAS_CONTEXT_PARAM, SQLLoginModul.VÝCHOZÍ_JAAS_KONTEXT);
    6.56  		setProperty(JAAS_CONTEXT_PARAM, jaasContext);
    6.57  
    6.58 -		log.log(Level.INFO, "SQLRealm úspěšně vytvořen. JaasContext: {0}", jaasContext);
    6.59 +		/** Databázové spojení */
    6.60 +		{
    6.61 +			String jndi = najdiParametr(parametry, PARAM_JNDI, "název datového zdroje");
    6.62 +			try {
    6.63 +				InitialContext k = new InitialContext();
    6.64 +				jndi = parametry.getProperty(PARAM_JNDI);
    6.65 +				datovýZdroj = (DataSource) k.lookup(jndi);
    6.66 +			} catch (NamingException e) {
    6.67 +				throw new BadRealmException("Datový zdroj s tímto názvem nebyl nalezen: " + jndi, e);
    6.68 +			}
    6.69 +		}
    6.70 +
    6.71 +		/** SQL dotazy */
    6.72 +		sqlHeslo = najdiParametr(parametry, PARAM_SQL_HESLO, "SQL dotaz pro ověření jména a hesla");
    6.73 +		sqlSkupinyUživatele = najdiParametr(parametry, PARAM_SQL_SKUPINY_UŽIVATELE, "SQL dotaz pro zjištění skupin uživatele");
    6.74 +		sqlSkupinyVšechny = najdiParametr(parametry, PARAM_SQL_SKUPINY_VŠECHNY, "SQL dotaz pro zjištění všech skupin");
    6.75 +
    6.76 +		_logger.log(Level.INFO, "SQLRealm úspěšně vytvořen. JaasContext: {0}", jaasContext);
    6.77  	}
    6.78 -
    6.79 +	
    6.80  	@Override
    6.81  	public String getAuthType() {
    6.82  		return AUTH_TYPE;
    6.83 @@ -41,24 +82,107 @@
    6.84  	 * @throws NoSuchUserException když uživatel s tímto jménem neexistuje.
    6.85  	 */
    6.86  	@Override
    6.87 -	public Enumeration getGroupNames(String uživatel) throws NoSuchUserException {
    6.88 -		throw new NoSuchUserException("Metoda zatím není implementována. Uživatel: " + uživatel);
    6.89 +	public Enumeration<String> getGroupNames(String uživatel) throws NoSuchUserException {
    6.90 +		Collection<String> skupiny = new ArrayList<>();
    6.91 +
    6.92 +		Connection s = null;
    6.93 +		PreparedStatement ps = null;
    6.94 +		ResultSet rs = null;
    6.95 +		try {
    6.96 +			s = datovýZdroj.getConnection();
    6.97 +			ps = s.prepareStatement(sqlSkupinyUživatele);
    6.98 +			ps.setString(1, uživatel);
    6.99 +			rs = ps.executeQuery();
   6.100 +
   6.101 +			while (rs.next()) {
   6.102 +				skupiny.add(rs.getString(1));
   6.103 +			}
   6.104 +
   6.105 +			return Collections.enumeration(skupiny);
   6.106 +
   6.107 +		} catch (Exception e) {
   6.108 +			String hláška = "Chyba při zjišťování skupin uživatele: " + uživatel + ".";
   6.109 +			_logger.log(Level.WARNING, hláška, e);
   6.110 +			throw new NoSuchUserException(hláška);
   6.111 +		} finally {
   6.112 +			zavri(s, ps, rs);
   6.113 +		}
   6.114  	}
   6.115  
   6.116  	/**
   6.117  	 * 
   6.118  	 * @param jméno uživatelské jméno
   6.119  	 * @param heslo heslo
   6.120 -	 * @return seznam skupin, do kterých uživatel patří
   6.121 +	 * @return true pokud je jméno a heslo v pořádku | false nikdy – vyhazuje výjimku
   6.122 +	 * @throws LoginException pokud je jméno nebo heslo neplatné nebo došlo k jiné chybě
   6.123  	 */
   6.124 -	public String[] ověřUživatele(String jméno, char[] heslo) throws LoginException {
   6.125 +	public boolean ověřUživatele(String jméno, char[] heslo) throws LoginException {
   6.126  
   6.127 -		// TODO: skutečně ověřovat heslo proti databázi
   6.128 +		Connection s = null;
   6.129 +		PreparedStatement ps = null;
   6.130 +		ResultSet rs = null;
   6.131 +		try {
   6.132 +			s = datovýZdroj.getConnection();
   6.133 +			ps = s.prepareStatement(sqlHeslo);
   6.134 +			ps.setString(1, jméno);
   6.135 +			ps.setString(2, new String(heslo));
   6.136 +			rs = ps.executeQuery();
   6.137  
   6.138 -		if (heslo != null && heslo.length == 3) {
   6.139 -			return new String[]{"bezny"};
   6.140 +			if (rs.next()) {
   6.141 +				String dbJméno = rs.getString(1);
   6.142 +				if (dbJméno.equals(jméno)) {
   6.143 +					// OK – úspěšné ověření
   6.144 +					return true;
   6.145 +				} else {
   6.146 +					throw new LoginException("Nebyl nalezen správný uživatel: " + jméno + " != " + dbJméno);
   6.147 +				}
   6.148 +			} else {
   6.149 +				throw new LoginException("Uživatel nebyl nalezen: " + jméno);
   6.150 +			}
   6.151 +		} catch (SQLException e) {
   6.152 +			String hláška = "SQL chyba při ověřování hesla uživatele: " + jméno + ".";
   6.153 +			_logger.log(Level.WARNING, hláška, e);
   6.154 +			throw new LoginException(hláška);
   6.155 +		} finally {
   6.156 +			zavri(s, ps, rs);
   6.157 +		}
   6.158 +	}
   6.159 +
   6.160 +	private String najdiParametr(Properties parametry, String názevParametru, String popis) throws BadRealmException {
   6.161 +		String hodnotaParametru = parametry.getProperty(názevParametru);
   6.162 +
   6.163 +		if (hodnotaParametru == null || hodnotaParametru.length() < 1) {
   6.164 +			throw new BadRealmException("Chybí " + popis + " – parametr: " + názevParametru);
   6.165  		} else {
   6.166 -			throw new LoginException("Heslo musí mít tři znaky :-P");
   6.167 +			return hodnotaParametru;
   6.168 +		}
   6.169 +	}
   6.170 +
   6.171 +	/**
   6.172 +	 * Zavře všechno
   6.173 +	 *
   6.174 +	 * @param spojeni DB spojení
   6.175 +	 * @param prikaz DB dotaz
   6.176 +	 * @param vysledek DB výsledek
   6.177 +	 */
   6.178 +	private static void zavri(Connection spojeni, Statement prikaz, ResultSet vysledek) {
   6.179 +		if (vysledek != null) {
   6.180 +			try {
   6.181 +				vysledek.close();
   6.182 +			} catch (Exception e) {
   6.183 +			}
   6.184 +		}
   6.185 +		if (prikaz != null) {
   6.186 +			try {
   6.187 +				prikaz.close();
   6.188 +			} catch (Exception e) {
   6.189 +			}
   6.190 +		}
   6.191 +		if (spojeni != null) {
   6.192 +			try {
   6.193 +				spojeni.close();
   6.194 +			} catch (Exception e) {
   6.195 +			}
   6.196  		}
   6.197  	}
   6.198  }
     7.1 --- a/java/sql-java-prihlasovani/test/cz/frantovo/jaas/sql/SQLRealmTest.java	Thu Jul 21 23:41:05 2011 +0200
     7.2 +++ b/java/sql-java-prihlasovani/test/cz/frantovo/jaas/sql/SQLRealmTest.java	Tue Feb 07 00:27:39 2012 +0100
     7.3 @@ -36,6 +36,7 @@
     7.4  	public void testGetAuthType() {
     7.5  		String authType = realm.getAuthType();
     7.6  		System.out.println("authType = " + authType);
     7.7 -		assertTrue("authType musí být nenulový a neprázdný", authType != null && authType.trim().length() > 0);
     7.8 +		assertTrue("authType musí být nenulový", authType != null);
     7.9 +		assertTrue("authType musí být neprázdný", authType.trim().length() > 0);
    7.10  	}
    7.11  }