Tuesday, October 22, 2013

JIRA JDBC Authentication Module

We have an internal request to configure our OpenAM to authenticate against the JIRA internal user store. 



I thought it was fairly easy and all I have to do is to write a custom password transformation class that implements JDBCPasswordSyntaxTransform. 


As easy as that. No.

By the way, the words underlined with blue are wrong. It should be "transform the clear-text password entered by user".


After exploring how the password is stored in JIRA internal user store (in our case, a Postgres database) , I realised passwords are encrypted with some kind of a salt such that a series of same clear-text passwords is represented differently after encryption.

As such, the only way to determine whether a clear-text password is the same as the one that is stored in the JIRA internal user store is to use a method isValidPassword in the PasswordEncoder class which is packaged in com.atlassian.security.password.


So this means I am left with no choice but to create a new authentication module for JIRA.


Not too much of a hassle though. What I did was to check out the source code of JDBC class from ForgeRock SVN.

Did nothing much, but to add the following code segment towards the end of process method.


        // for JIRA password comparison, we are expecting clear text to be used 
        // against JIRA API         
        if (!transform.equals(DEFAULT_TRANSFORM)) {
            if (debug.messageEnabled()) {
                debug.message("Syntax Transform Exception: ClearTextTransform expected!");
            }
            throw new AuthLoginException(amAuthJDBC, "ClearTextTransform expected",null);
        }

// Get an instance of JIRA password encoder which is based on PKCS5S2
PasswordEncoder pe = DefaultPasswordEncoder.getDefaultInstance();

        // see if the passwords match
        if (password != null && pe.isValidPassword(password, resultPassword)) {            
            userTokenId = userName;
            return ISAuthConstants.LOGIN_SUCCEED;
        } else {           
            debug.message("password not match. Auth failed.");
            setFailureID(userName);
            throw new InvalidPasswordException(amAuthJDBC, "loginFailed",
                null, userName, null);
        }



.

No comments:

Post a Comment