0 Replies Latest reply on May 26, 2009 7:06 AM by shivaji.byrapaneni

    JAAS in Jboss 5.0 GA

      Hi 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 method 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