JAAS in Jboss 5.0 GA
shivaji.byrapaneni May 26, 2009 6:29 AMHi There,
im a new bee to Jboss and JAAS as well
i tried to implement soem thing on jboss with jaas like this
1) a Login Page popup to teh user asking dor user id & password
2) After he clicks on login i thught of validating that using JAAS
3) If login is returned succesful i though of putting the subject in session for my future actions on th applications
im using
jsf 1.2 with richfaces
Jboss 5.0 GA
Here is what i did
1) I had created a configuration file like this
nomination_authenticator.config
/** Login Configuration for the JAAS Sample Application **/
NominationSystem {
com.security.login.SecurityLoginModule required debug=true;
};
2) is one of my startup filter in my init i did this
System.setProperty("-Djava.security.auth.login.config",
"nomination_authenticator.config
");
nomination_authenticator.config is available in my classpath.
3) i wrote a Autheticator in which a method will be called from my managed bean after collecting the user id and password which usre provides on screen
package com.authentication;
import java.io.IOException;
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.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import com.logger.NominationLogger;
public class Authenticator {
public static boolean AuthenticateUser(String userid, String password) throws Exception {
LoginContext lc = null;
try {
lc = new LoginContext("NominationSystem",
new AuthenticatorCallbackHandler(userid, password));
} catch (LoginException le) {
NominationLogger.error("Cannot create LoginContext. "
+ le.getMessage());
throw le;
} catch (SecurityException se) {
NominationLogger.error("Cannot create LoginContext. "
+ se.getMessage());
throw se;
}
try {
lc.login();
} catch (LoginException e) {
NominationLogger.error("Login Error" + e.getMessage());
throw e;
}
return false;
}
}
class AuthenticatorCallbackHandler implements CallbackHandler {
private String userId = null;
private String password = null;
public AuthenticatorCallbackHandler(String userId, String password) {
this.userId = userId;
this.password = password;
}
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks instanceof NameCallback) {
NameCallback nc = (NameCallback) callbacks;
nc.setName(userId);
} else if (callbacks instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callbacks;
pc.setPassword(getPasswordAsCharArray(password));
} else {
throw new UnsupportedCallbackException(callbacks,
"Unrecognized Callback");
}
}
}
private char[] getPasswordAsCharArray(String password) {
char[] charArrPassword = null;
charArrPassword = new char[password.length()];
for (int i = 0; i < password.length(); i++)
charArrPassword = password.charAt(i);
return charArrPassword;
}
}
bold font methos will be called from my managed bean with user id and password.
and my Login module is this
package com.security.login;
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.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import com.logger.NominationLogger;
import com.managedbeans.NominationBaseBean;
public class SecurityLoginModule implements javax.security.auth.spi.LoginModule {
// initial state
private Subject subject;
private CallbackHandler callbackHandler;
private Map sharedState;
private Map options;
// configurable option
private boolean debug = false;
// the authentication status
private boolean succeeded = false;
private boolean commitSucceeded = false;
// username and password
private String userId;
private String password;
private String role;
private String name;
// principle object
private NominationPrinciple nominationPrincipal;
public void initialize(Subject subject, CallbackHandler callbackHandler,
Map sharedState, Map options) {
this.subject = subject;
this.callbackHandler = callbackHandler;
this.sharedState = sharedState;
this.options = options;
// initialize any configured options
debug = "true".equalsIgnoreCase((String) options.get("debug"));
}
public boolean login() throws LoginException {
// prompt for a user name and password
if (callbackHandler == null)
throw new LoginException("Error: no CallbackHandler available "
+ "to garner authentication information from the user");
Callback[] callbacks = new Callback[2];
callbacks[0] = new NameCallback("user name: ");
callbacks[1] = new PasswordCallback("password: ", false);
try {
callbackHandler.handle(callbacks);
userId = ((NameCallback) callbacks[0]).getName();
char[] tmpPassword = ((PasswordCallback) callbacks[1])
.getPassword();
password = getPasswordAsString(tmpPassword);
((PasswordCallback) callbacks[1]).clearPassword();
} catch (java.io.IOException ioe) {
throw new LoginException(ioe.toString());
} catch (UnsupportedCallbackException uce) {
throw new LoginException("Error: " + uce.getCallback().toString()
+ " not available to garner authentication information "
+ "from the user");
}
// print debugging information
if (debug) {
NominationLogger.debug("user id: " + userId);
NominationLogger.debug("Password: " + password);
}
// verify the username/password
boolean usernameCorrect = false;
boolean passwordCorrect = false;
// Hit db here with user id and password and get the details
// assign role to role variable
if (userId.equals("testUser"))
usernameCorrect = true;
if (usernameCorrect && password.equals("testPassword")) {
// authentication succeeded!!!
passwordCorrect = true;
if (debug)
NominationLogger.debug("authentication succeeded");
// seeting some test role
role = "testRole";
// setting test name
name = "Shivaji";
succeeded = true;
return true;
} else {
// authentication failed -- clean out state
if (debug)
NominationLogger.debug("authentication failed");
succeeded = false;
userId = null;
password = null;
throw new FailedLoginException("Invalid login");
}
}
public boolean commit() throws LoginException {
if (succeeded == false) {
return false;
} else {
nominationPrincipal = new NominationPrinciple(name, role, userId);
if (!subject.getPrincipals().contains(nominationPrincipal))
subject.getPrincipals().add(nominationPrincipal);
if (debug) {
NominationLogger.debug("added SamplePrincipal to Subject");
}
// setting subject to session
new NominationBaseBean().getNominationSessionBean().setSubject(
subject);
// in any case, clean out state
userId = null;
password = null;
name = null;
role = null;
commitSucceeded = true;
return true;
}
}
public boolean abort() throws LoginException {
if (succeeded == false) {
return false;
} else if (succeeded == true && commitSucceeded == false) {
// login succeeded but overall authentication failed
succeeded = false;
userId = null;
role = null;
password = null;
name = null;
nominationPrincipal = null;
} else {
// overall authentication succeeded and commit succeeded,
// but someone else's commit failed
logout();
}
return true;
}
public boolean logout() throws LoginException {
subject.getPrincipals().remove(nominationPrincipal);
succeeded = false;
succeeded = commitSucceeded;
userId = null;
role = null;
password = null;
name = null;
nominationPrincipal = null;
return true;
}
private String getPasswordAsString(char[] password) {
StringBuffer stringPassword = new StringBuffer();
for (int i = 0; i < password.length; i++)
stringPassword.append("" + password);
return stringPassword.toString();
}
}
in my web.xml i added this
<security-constraint> <!-- A collection of protected resources along with the access mechanism --> <web-resource-collection> <web-resource-name>Restricted to Secure role</web-resource-name> <description>Declarative security</description> <url-pattern>/*</url-pattern> <http-method>HEAD</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> <http-method>DELETE</http-method> </web-resource-collection> <!-- The list of roles that can access the resource. --> <auth-constraint> <role-name>User</role-name> <role-name>Approver</role-name> <role-name>Account_L_D</role-name> <role-name>L_D</role-name> </auth-constraint> </security-constraint>
in my web-inf i added jboss-web.xml
<?xml version="1.0" encoding="UTF-8"?> <jboss-web> <security-domain>java:/jaas/NominationSecurity</security-domain> </jboss-web>
i added thsi in my login-config.xml
<application-policy name="NominationSecurity"> <authentication> <login-module code="com.security.login.SecurityLoginModule" flag="required"> <module-option name="usersProperties">props/nominationSystem-users.properties</module-option> </login-module> </authentication> </application-policy>
this is all what i did for my application
but when i tried to access the login page it giving me access denied
im sure that i did something absured pls correct me if i.
please help me in understanding and making my wish working...
Thanks a lot in advance