3 Replies Latest reply on Apr 10, 2012 5:35 PM by zeeman

    Password hash with seam-security

    baraber

      Hello,

      I'm using seam-security, with the picketLink model (JPAIdentityStore and IdmAuthenticator).

       

      Does seam-security allow to automatically handle password hashing ?

      I've seen the PasswordHash, PasswordHashEncoder and CredentialProcessor in seam-security-impl, but cannot figure how these classes are meant to be used, or event if they are meant to be used by an application at all (since it's not in the API).

       

      So I made it my way, created a class implementing picketlink stuff ( Credential, IdentityObjectCredential ), that just encode its value :

       

       

      {code}

      public class Sha1PasswordCredentialImpl extends AbstractCredential {

          private String originalValue;

          private String hashedValue;

       

          public Sha1PasswordCredentialImpl(String originalValue) {

              super(new SimpleCredentialType("HASHED_PASSWORD_SHA1"));

              this.originalValue = originalValue;

              this.hashedValue = HashUtils.sha1(originalValue);

          }

       

          @Override

          public Object getValue() {

              return hashedValue;

          }

       

          @Override

          public Object getEncodedValue() {

              throw new UnsupportedOperationException("Not supported yet.");

          }

       

      }

      {code}

       

      Then I had to insert this new "CredentialType" into my database :

       

       

      {code}

      IdentityObjectCredentialType hashedPassword = new IdentityObjectCredentialType();

      hashedPassword.setName("HASHED_PASSWORD_SHA1");

      em.persist(hashedPassword);

      {code}

       

      Made my login form call "credentials.credential" instead of(credentials.password) in my password input field :

       

      {code:xml}<h:inputSecret id="password" value="#{credentials.credential}" redisplay="true" converter="passwordConverter"/>{code}


      And finally had to create a converter for my "Sha1PasswordCredentialImpl" :

       

      {code}

      @FacesConverter("passwordConverter")

      public class PasswordCredentialConverter implements Converter {

       

          @Override

          public Object getAsObject(FacesContext context, UIComponent component, String value) {

              return new Sha1PasswordCredentialImpl(value);

          }

       

          @Override

          public String getAsString(FacesContext context, UIComponent component, Object value) {

              Sha1PasswordCredentialImpl c = (Sha1PasswordCredentialImpl) value;

              return value == null ? null:(String)c.getValue();

          }

       

      }

      {code}

       

      This works pretty fine but ...

       

      We plan to create many application : one to manage the security model (feeding the database with users, groups, etc) (an "IdmConsole")  and the others are the "real" business applications, that just use the database with seam 3 (login, role checks etc).

       

      So, if I keep my solution, I'll have to bring my new Credential implementation with the faces converter in all of these applications.

       

      That is why I'm wondering if I can achieve the same behavior just by configuring seam-security differently.

       

      PS : I also noted that the "org.picketlink.idm.impl.api.PasswordCredential" that seam-security uses by default provide a "getEncodedValue" method, that encode the password using md5.  If I could just tell picketLink to take advantage of that method, that would do the  job.  However I don't think I can do it.

        • 1. Re: Password hash with seam-security
          zeeman

          To avoid all of this hassle. I hande psw hash myself. I have a psw hash column in user account table. When user logs in, in authenticate method I had the psw and compare to what's in the DB. I use sha1 hash. You get that right out of the JDK. I made a util class to use in authenticate method.

           




          final MessageDigest md = MessageDigest.getInstance("SHA-256");



          md.update(password.getBytes("UTF-8"));



          final byte[] raw = md.digest();

           

          you'll need to use a hex encoder when converting to String.

           

           

          I use org.apache.commons.codec.binary.Hex;.

           

          return new String(Hex.encodeHex(raw));

          • 2. Re: Password hash with seam-security
            baraber

            Oh, I have no problem with the hash stuff, but I didn't know about commons-codec.   Thank you for this.

             

            Did you provide your own authenticator ? 

             

            I'd prefer to use the IdmAuthenticator.

            • 3. Re: Password hash with seam-security
              zeeman

              I just use an authenticator that implements the seam security authenticator interface. Check out security examples on github.com/seam/security