Security management with Jaas on a Tomcat server
[30 mn de lecture - paru le 11/11/2004 4:12:38 PM - Public : Confirmé]
|
   
|
Auteur
2. Java class
The Java class must be placed with the shared class in the repertoire /common/classes/ or in /common/lib/ if you exported your project in .jar.
They will reach the data base and determine if the user has the neccessaires roles to see the application.
2.1. JDBCLoginModule.java
JDBCLoginModule is the principal class which carries out all the treatment of information. It recovers the login and the password of the user,
them compare with the instencie and data base then UserPrincipal and RolePrincpal. Here the code with accompanying notes of this class:
/*
* Created on 26 oct. 2004
*/
package auth;
/**
* @author eju
*/
// import lists
import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
import javax.security.auth.Subject;
import javax.security.auth.callback.*;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
import javax.sql.DataSource;
public class JDBCLoginModule implements LoginModule {
private boolean debug = false;
private boolean succeeded = false;
private boolean commitSucceeded = false;
private String errorfile;
private String userName = null;
private String userPass = null;
private String logFile = null;
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private UserPrincipal userPrincipal = null;
private Vector rolePrincipals = new Vector();
private DataSource dsBdInfoLib;
private PreparedStatement pstmt=null;
private ResultSet rs=null;
public JDBCLoginModule() {
}
public void initialize(Subject subject, CallbackHandler callbackhandler,
Map sharedState, Map options) {
this.subject = subject;
this.callbackHandler = callbackhandler;
this.sharedState = sharedState;
debug = "true".equalsIgnoreCase((String)options.get("debug"));
if((String)options.get("logfile") != null){
logFile = (String)options.get("logfile");
}
else {
logFile = "";
debug = false;
}
}
public boolean login() throws LoginException {
try {
authenticate();
succeeded = true;
logError("authentication succeeded");
return true;
} catch (LoginException le) {
logError("authentication failed" + le.toString());
reset();
throw le;
}
}
public boolean abort() throws LoginException {
if (succeeded == false) return false;
if (succeeded == true && commitSucceeded == false) {
reset();
} else {
logout();
}
return true;
}
// Requete allowing to know if the user exists
public String makeRequeteAuth(){
StringBuffer sql=new StringBuffer();
sql.append("select nom_appauv ");
sql.append("from compte_libraires ");
sql.append("where nom_appauv = ? ");
sql.append("and mdp = ? ");
return sql.toString();
}
// Requete allowing to bring back the role(s) of the user
public String makeRequeteRole(){
StringBuffer sql=new StringBuffer();
sql.append("select cat.nom_appauv ");
sql.append("from compte_libraires c, cat_libraires cat ");
sql.append("where c.cat_code = cat.code ");
sql.append("and c.nom_appauv = ? ");
sql.append("and c.mdp = ? ");
return sql.toString();
}
private void authenticate() throws LoginException {
Connection conBdInfoLib=null;
int authverif = 0;
if (callbackHandler == null)
throw new LoginException("ERROR: no CallbackHandler " +
"available to garner authentication information " +
"from the user");
Callback authCB[] = new Callback[2];
authCB[0] = new NameCallback("Username: ");
authCB[1] = new PasswordCallback("Password: ", false);
try {
callbackHandler.handle(authCB);
// Recover the login of the user
userName = ((NameCallback)authCB[0]).getName();
if (userName != null) {
userName = userName.toUpperCase();
}
// Recover the password of the user
char ac[] = ((PasswordCallback)authCB[1]).getPassword();
char password[] = new char[ac.length];
System.arraycopy(ac, 0, password, 0, ac.length);
userPass = new String(password);
if (userPass != null) {
userPass = userPass.toUpperCase();
}
((PasswordCallback)authCB[1]).clearPassword();
// Connection initialization with the data base
Context initialCtx = new InitialContext();
Context ctx = (Context)initialCtx.lookup("java:comp/env");
dsBdInfoLib=(DataSource)ctx.lookup("jdbc/WebBdInfoLibraires");
synchronized (dsBdInfoLib) {
conBdInfoLib = dsBdInfoLib.getConnection();
}
// First request preparedstatement + execution
pstmt = conBdInfoLib.prepareStatement(makeRequeteAuth(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
pstmt.setString(1, userName);
pstmt.setString(2, userPass);
rs = pstmt.executeQuery();
if(!rs.next()){
logError("Nom d'utilisateur inconnu");
throw new LoginException("Nom d'utilisateur inconnu");
}
else {
logError("Nom d'utilisateur CONNU !!!");
}
rs.close();
pstmt.close();
// Instantiation of the UserPrincipal class
userPrincipal = new UserPrincipal(userName);
// Second request preparedstatement + execution
pstmt = conBdInfoLib.prepareStatement(makeRequeteRole(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
pstmt.setString(1, userName);
pstmt.setString(2, userPass);
rs = pstmt.executeQuery();
while (rs.next()){
String role = rs.getString("NOM_APPAUV");
if (rs.wasNull()) {throw new LoginException("Accès refusé : role non défini.");}
logError(role);
// nstantiation of the RolePrincipal class
RolePrincipal rolePrincipal = new RolePrincipal(role);
// Addition of the object in the vector rolePrincipals
rolePrincipals.addElement(rolePrincipal);
}
//recuperer le role boucle while
//String s = "";
//RolePrincipal rolePrincipal = new RolePrincipal(s);
//rolePrincipals.addElement(rolePrincipal);
}
// Gestion des exceptions
catch(IOException ioe) {
throw new LoginException(ioe.toString());
}
catch(NamingException ne) {
logError("unable to find user: " + ne.toString());
throw new FailedLoginException("User not found");
}
catch(UnsupportedCallbackException uce) {
throw new LoginException("Error: " + uce.getCallback().toString() + " not available to get auth info from user");
}
catch (Exception e){
throw new LoginException(e.getMessage());
}
finally {
try {
if (rs != null) {
rs.close();
rs = null;
}
if (pstmt != null) {
pstmt.close();
pstmt = null;
}
if (conBdInfoLib != null) {
conBdInfoLib.close();
conBdInfoLib = null;
}
} catch (SQLException e1) {}
}
}
public boolean commit() throws LoginException {
if (succeeded == false) return false;
if (!subject.getPrincipals().contains(userPrincipal)) {
subject.getPrincipals().add(userPrincipal);
logError("added UserPrincipal to Subject");
}
Enumeration e = rolePrincipals.elements();
while (e.hasMoreElements()) {
RolePrincipal rolePrincipal =
(RolePrincipal)e.nextElement();
if (!subject.getPrincipals().contains(rolePrincipal)) {
subject.getPrincipals().add(rolePrincipal);
logError("added role principal");
}
}
userName = null;
userPass = null;
commitSucceeded = true;
return true;
}
public boolean logout() throws LoginException {
subject.getPrincipals().remove(userPrincipal);
succeeded = false;
commitSucceeded = false;
reset();
logError("logged out");
return true;
}
private void logError(String msg) {
PrintWriter printer;
if (debug) {
try {
printer = new PrintWriter(new BufferedWriter(new FileWriter(logFile , true)));
printer.println(msg);
printer.close();
} catch (IOException e) {
e.printStackTrace();
e.getMessage();
}
}
}
private void reset() {
userName = null;
userPass = null;
userPrincipal = null;
rolePrincipals.clear();
}
}
|
2.2. UserPrincipal.java
The userPrincipal class is used by the realm thanks to the parameter userClassNames="auth.UserPrincipal " present in the Infolibraires.xml file.
/*
* Created on 26 oct. 2004
*/
package auth;
/**
* @author eju
*/
import java.security.Principal;
public class UserPrincipal implements Principal, java.io.Serializable {
private String name;
public UserPrincipal (String name) {
if (name == null)
throw new NullPointerException("illegal null input");
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
String className = getClass().getName();
return className.substring(className.lastIndexOf('.') + 1) + ": " + name;
//return("com.galatea.java.auth.UserPrincipal: " + name);
//return name;
}
public boolean equals(Object o) {
if (o == null) return false;
if (this == o) return true;
if (!(o instanceof UserPrincipal)) return false;
UserPrincipal that = (UserPrincipal)o;
if (this.getName().equals(that.getName())) return true;
return false;
}
public int hashCode() {
return name.hashCode();
}
}
|
2.3. RolePrincipal.java
The rolePrincipal class is used by the realm thanks to the parameter roleClassNames="auth.RolePrincipal " present in the Infolibraires.xml file.
/*
* Created on 26 oct. 2004
*/
package auth;
/**
* @author eju
*/
import java.security.Principal;
public class RolePrincipal implements Principal, java.io.Serializable {
private String name;
public RolePrincipal (String name) {
if (name == null)
throw new NullPointerException("illegal null input");
this.name = name;
}
public String getName() {
return name;
}
public String toString() {
//return("com.galatea.java.auth.RolePrincipal: " + name);
String className = getClass().getName();
return className.substring(className.lastIndexOf('.') + 1) + ": " + name;
//return name;
}
public boolean equals(Object o) {
if (o == null) return false;
if (this == o) return true;
if (!(o instanceof RolePrincipal)) return false;
RolePrincipal that = (RolePrincipal)o;
if (this.getName().equals(that.getName())) return true;
return false;
}
public int hashCode() {
return name.hashCode();
}
}
|
|