1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
|
package my;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
public class RDBLoginModule implements LoginModule {
// Etat initial, nécessaire par l'implements
CallbackHandler callbackHandler; // Chargé de l'interface avec l'utilisateur ou tout autre moyen d'authentification
Subject subject; // Informations concernant l'identification (princiapl, credential, nom, ...)
Map sharedState; // Informations partagées entre les différents LoginModule
Map options; // Options complémentaires du fichier de configuration, ici, l'URL et le driver d'accès à la base de données
// Etat temporaire, stockage temporaire des informations d'identification
// Une personne peut être identifié par son nom, N°= sécu, ... == Tableau
ArrayList tempCredentials; // Nom ou clé publique
ArrayList tempPrincipals; // mot de passe ou clé privée
// Statut d'authentification
boolean success; // true si ok !
// Options de configuration récupérées dans le fichier de configuration
String jdbcUrl; // URL d'accès à la base de données
String jdbcDriver; // Pilote d'accès à la base de données
String jdbcTable; // Table contenant les informations de connexion
String userField; // Champs contenant les informations du nom/login de l'utilisateur
String passField; // Champs contenant le mot de passe de l'utilisateur
String nameField; // Nom de l'utilisateur
String fornameField; // Prénom de l'utilisateur
String insertPerm; // Champs contenant la valeur de la permission d'insérer
String deletePerm; // Champs contenant la valeur de la persmission de supprimer
String updatePerm; // Champs contenant la valeur de la permission de mettre à jour
String selectPerm; // Champs contenant la valeur de la permission de visualiser les données
private boolean commited;
public RDBLoginModule() {
tempCredentials = new ArrayList();
tempPrincipals = new ArrayList();
success = false;
jdbcUrl = null;
jdbcDriver = null;
jdbcTable = null;
userField = null;
passField = null;
nameField = null;
fornameField = null;
insertPerm = null;
deletePerm = null;
updatePerm = null;
selectPerm = null;
callbackHandler = null;
subject = null;
sharedState=null;
options=null;
System.out.println("depuis construct RDBLoginmodule");
commited = false;
}
public boolean abort() throws LoginException {
success = false;
tempPrincipals.clear();
tempCredentials.clear();
if (callbackHandler instanceof PassiveCallbackHandler)
((PassiveCallbackHandler)callbackHandler).clearPassword();
logout();
return true;
}
public boolean commit() throws LoginException {
if (success) {
try {
subject.getPrincipals().addAll(tempPrincipals);
subject.getPrincipals().add(new RDBRolePrincipal("admin"));
} catch (Exception e) {
e.printStackTrace();
throw new LoginException(e.getMessage());
}
}
commited=true;
return true;
}
public boolean login() throws LoginException {
// Y a-t-il bien un CallbackHandler initialisé ?
if (callbackHandler == null) {
throw new LoginException("Erreur: pas de callback !");
}
try {
// initialisation des callbacks
Callback[] callbacks = new Callback[]{
// Callback pour retrouver les informations de Nom, l'argument est le prompt à afficher
new NameCallback("Nom:"),
// Callback pour le mot de passe, prompt et true pour afficher le mot de passe en le tapant
new PasswordCallback("Mot de passe:",false)
};
// Appel de la méthode handle pour récupérer les informations d'identification
// La méthode dce récupération ne nous interesse pas ici, seul nous intéresse la récupération
// du user et du mot de passe ou des clés
callbackHandler.handle(callbacks);
// Récupération des informations
// L'ordre des données est donné plus haut
String userName = ((NameCallback)callbacks[0]).getName();
String password = new String(((PasswordCallback)callbacks[1]).getPassword());
// Clear du password dans le callbacks
((PasswordCallback)callbacks[1]).clearPassword();
// Validation des informations
success = rdbValidate(userName, password);
// Annulation des callbacks
callbacks[0]=null;
callbacks[1]=null;
if (!success) {
throw new LoginException("Authentification incorrecte !");
}
return success;
} catch (Exception ex) {
}
return false;
}
public boolean logout() throws LoginException {
// clear des informations utilisateur et autorisations
tempPrincipals.clear();
tempCredentials.clear();
if (callbackHandler instanceof PassiveCallbackHandler)
((PassiveCallbackHandler)callbackHandler).clearPassword();
// Clear des informations enregistrées dans le Subject
Iterator it = subject.getPrincipals().iterator();
while (it.hasNext()) {
RDBPrincipal p = (RDBPrincipal)it.next();
subject.getPrincipals().remove(p);
}
it = subject.getPublicCredentials().iterator();
while (it.hasNext()) {
RDBCredential c = (RDBCredential)it.next();
subject.getPublicCredentials().remove(c);
}
return true;
}
public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState,
Map options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
// récupération et initialisation des options
jdbcUrl = (String) options.get("url");
jdbcDriver = (String) options.get("driver");
jdbcTable = (String) options.get("table");
userField = (String) options.get("userField");
passField = (String) options.get("passField");
nameField = (String) options.get("nameField");
fornameField = (String) options.get("fornameField");
insertPerm = (String) options.get("insertPerm");
deletePerm = (String) options.get("deletePerm");
updatePerm = (String) options.get("updatePerm");
selectPerm = (String) options.get("selectPerm");
System.out.println("depuis init RDBLoginmodule");
}
private boolean rdbValidate(String userName, String password) throws LoginException {
System.out.println("depuis validate RDBLoginmodule");
Connection con;
// Query avec les champs personnalisés
String query = "SELECT * FROM " + jdbcTable + " where " + userField + "='" + userName + "'";
Statement stmt;
RDBPrincipal p = null;
RDBCredential c = null;
boolean passwordMatch = false;
try {
Class.forName(jdbcDriver);
} catch (ClassNotFoundException cnfex) {
throw new LoginException("Pilote JDBC introuvable, vérifier votre CLASSPATH");
}
try {
// Effectue la connexion à la base de données, requête sur l'utilisateur
// récupération des données
con = DriverManager.getConnection(jdbcUrl,"sa","admin");
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
String dbPassword = null, dbFname = null, dbLname = null;
String updatePerm = null, deletePerm = null, insertPerm=null, selectPerm=null;
boolean isEqual = false;
while (rs.next()) {
// Test en dur !!!
dbPassword = "jamaïc";
dbFname = "bob";
dbLname = "marley";
insertPerm = "1";
deletePerm = "1";
updatePerm = "1";
selectPerm = "1";
}
// Password null == utilisateur introuvable
if (dbPassword==null)
throw new LoginException("Utilisateur ou mot de passe incorrect !");
passwordMatch = password.equals(dbPassword);
// Principals et Credentials
if (passwordMatch) {
c = new RDBCredential();
c.setProperty("insertPerm",insertPerm);
c.setProperty("deletePerm",deletePerm);
c.setProperty("updatePerm",updatePerm);
c.setProperty("selectPerm",selectPerm);
this.tempCredentials.add(c);
this.tempPrincipals.add(new RDBPrincipal(dbFname + " " + dbLname));
}
rs.close();
stmt.close();
con.close();
} catch (SQLException sqlex) {
sqlex.printStackTrace() ;
System.out.println("exception capturée SQL");
throw new LoginException(sqlex.getMessage());
}
return passwordMatch;
}
static public void main(String args[]) throws Exception{
LoginContext ctx = new LoginContext("RDBLogin");
System.out.println("depuis constructeur RDBLoginmodule");
ctx.login();
}
} |
Partager