I can't find what's wrong with my custom realm implementation.
Notice that on each function I output a server log message so I can identify it, however non of those appear on the server log, only the error described previously.
Here are my files:
The Login Module class:
--------------------------------------------
package com.expolang.security.sunappserv;
import javax.security.auth.login.LoginException;
import com.sun.appserv.security.AppservPasswordLoginModule;
import java.util.logging.Level;
/**
* Implements JAAS LoginModule as part of the ExpoLangRealm custom realm.
*/
public class ExpoLangLoginModule extends AppservPasswordLoginModule {
@Override
protected void authenticateUser() throws LoginException {
_logger.log(Level.INFO, "ExpoLangLoginModule start");
// Get the current realm and check whether it is instance of your realm
if (!(_currentRealm instanceof ExpoLangRealm)) {
throw new LoginException("ExpoLangLoginModule: Realm is not a ExpoLangRealm.");
}
ExpoLangRealm myCustomRealm = (ExpoLangRealm) _currentRealm;
String[] grpList = myCustomRealm.authenticateUser(_username, _password);
_logger.log(Level.INFO, "ExpoLangLoginModule after authenticateUser");
if (grpList == null) // JAAS behavior
{
throw new LoginException("ExpoLangLoginModule: Login Failed with user " + _username);
}
// Database authentication:
_logger.log(Level.FINE, "ExpoLangLoginModule returning groups");
_logger.log(Level.WARNING, "ExpoLangLoginModule returning groups");
commitUserAuthentication(grpList);
}// authenticateUser()
}// class ExpoLangLoginModule
--------------------------------------------
The Realm class:
--------------------------------------------
package com.expolang.security.sunappserv;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
import com.sun.appserv.security.AppservRealm;
import com.sun.enterprise.security.auth.realm.BadRealmException;
import com.sun.enterprise.security.auth.realm.NoSuchUserException;
import com.sun.enterprise.security.auth.realm.NoSuchRealmException;
import com.sun.enterprise.security.auth.realm.InvalidOperationException;
/**
* ExpoLangRealm for supporting RDBMS authentication.
*
* sample setting in domain.xml for ExpoLangeLoginModule
* <auth-realm name="ExpoLangRealm" classname="com.expolang.security.expolangrealm">
* <property name="dbdrivername" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
* <property name="dburl" value="jdbc:sqlserver://192.168.0.101:1433;databaseName=ExpoLang"/>
* <property name="dbusername" value="public"/>
* <property name="dbpasswd" value="public"/>
* <property name="dbauthfunction" value="dbfunc"/>
* </auth-realm>
*/
public final class ExpoLangRealm extends AppservRealm {
static final String AUTH_TYPE = "ExpoLangRealm";
static final String AUTH_TYPE_PARAM = "auth-type";
private String authType = null;
static final String PARAMS_DBDRIVERNAME = "dbdrivername";
private String dbDriverName = null;
static final String PARAMS_DBURL = "dburl";
private String dbUrl = null;
static final String PARAMS_DBUSERNAME = "dbusername";
private String dbUsername = null;
static final String PARAMS_DBPASSWD = "dbpasswd";
private String dbPassword = null;
static final String PARAMS_DBAUTHFUNCTION = "dbauthfunction";
private String dbAuthFunction = null;
private Properties _realmProperties = null;
private Vector<String> _emptyVector;
private String[] _emptyStringArray;
static Driver _dbdriver = null;
static Connection _dbConnection = null;
/*
public ExpoLangRealm() {
}// ExpoLangRealm()
*/
/**
* Initialize a realm with some properties. This can be used
* when instantiating realms from their descriptions. This
* method may only be called a single time.
*
* @param props Initialization parameters used by this realm.
* @exception BadRealmException If the configuration parameters
* identify a corrupt realm.
* @exception NoSuchRealmException If the configuration parameters
* specify a realm which doesn't exist.
*
*/
@Override
protected void init(Properties props)
throws BadRealmException, NoSuchRealmException {
super.init(props);
_realmProperties = props;
_emptyVector = new Vector<String>();
_emptyStringArray = new String[0];
String jaasCtx = props.getProperty(AppservRealm.JAAS_CONTEXT_PARAM);
this.setProperty(AppservRealm.JAAS_CONTEXT_PARAM, jaasCtx);
// Load realm properties:
try {
authType = getProp(AUTH_TYPE_PARAM);
} catch (BadRealmException bre) {
authType = AUTH_TYPE;
}
dbDriverName = getProp(PARAMS_DBDRIVERNAME);
dbUrl = getProp(PARAMS_DBURL);
dbUsername = getProp(PARAMS_DBUSERNAME);
dbPassword = getProp(PARAMS_DBPASSWD);
dbAuthFunction = "{call " + getProp(PARAMS_DBAUTHFUNCTION) + "(?, ?)}";
System.out.println("\nExpoLangRealm initialized successfuly.\n");
}// init(Properties)
private String getProp(String propertyName) throws BadRealmException {
String propValue = _realmProperties.getProperty(propertyName);
if (propValue == null) {
throw new BadRealmException("Field " + propertyName + " does not exist in realm configuration.");
}
return propValue;
}// String getProp(String)
/**
* Returns a short description of the kind of authentication which is
* supported by this realm.
*
* @return Description of the kind of authentication that is directly
* supported by this realm.
*/
@Override
public String getAuthType() {
System.out.println("ExpoLangRealm: using getAuthType()");
return this.authType;
}// String getAuthType()
/**
* Returns the name of all the groups that this user belongs to.
* @param username Name of the user in this realm whose group listing
* is needed.
* @return Enumeration of group names (strings).
* @exception InvalidOperationException thrown if the realm does not
* support this operation - e.g. Certificate realm does not support
* this operation.
*/
public Enumeration<String> getGroupNames(String username)
throws InvalidOperationException, NoSuchUserException {
System.out.println("\nExpoLangRealm getGroupNames(String username = " + username + ")\n");
Vector<String> x = new Vector<String>();
x.add("ExpoLang");
return x.elements();
//return _emptyVector.elements();
}// Enumeration<String> getGroupNames(String)
/**
* Return the user group associated with the specified username and
* credentials, if there is one; otherwise return <code>null</code>.
*
* @param username
* the user's id
* @param passwd
* the user's clear password
*/
public String[] authenticateUser(String username, String passwd) {
System.out.println("Begin authenticating " + username + "...");
ArrayList<String> userGroups = new ArrayList<String>();
CallableStatement cs = null;
try {
Connection conn = getConnection();
cs = conn.prepareCall(dbAuthFunction);
cs.setString(1, username);
cs.setString(2, passwd);
ResultSet rs = cs.executeQuery();
String group;
while (rs.next()) {
group = rs.getString(1).trim();
if (!userGroups.contains(group)) {
userGroups.add(group);
}
}
} catch (SQLException e) {
e.printStackTrace();
System.out.println("ExpoLangRealm: Error connecting to database.");
} finally {
try {
cs.close();
} catch (SQLException ignore) {
ignore.printStackTrace();
}
}
System.out.println("ExpoLangRealm: Finished authenticating. Size of array: " + userGroups.size());
return userGroups.toArray(_emptyStringArray);
}// String[] authenticate(String, String)
/**
* Get JDBC connection.
*/
private Connection getConnection() throws SQLException {
if (_dbConnection != null) {
return (_dbConnection);
}
String dbdrivername = dbDriverName;
String dburl = dbUrl;
String dbusername = dbUsername;
String dbpasswd = dbPassword;
if (_dbdriver == null) {
try {
Class<?> clazz = Class.forName(dbdrivername);
_dbdriver = (Driver) clazz.newInstance();
} catch (Throwable e) {
throw new SQLException(e.getMessage());
}
}
// Open a new connection
Properties props = new Properties();
props.put("user", dbusername);
props.put("password", dbpasswd);
Connection dbcon = _dbdriver.connect(dburl, props);
dbcon.setAutoCommit(false);
return dbcon;
}// Connection getConnection()
}// class ExpoLangRealm
--------------------------------------------
Thanks alot for helping!
[Message sent by forum member 'bobohaskel' (bobohaskel)]
http://forums.java.net/jive/thread.jspa?messageID=260105