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 |
}
|