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