2

I'm attempting to use Shiro for Authentication and Authorization for a JSF Web Application I'm building. Unfortunately, I'm still having some difficulty wrapping my head around how it all fits together.

I've been successful (100% using the shiro.ini file) configuring authentication back to a JDBC realm where a test set of credentials are stored. It has worked perfectly for me when credentials are stored in plaintext.

My ultimate goal is to unify an existing credential set in a MySQL database. The passwords are stored as SHA-256 salted hashes. I've spent an entire day reading over the documentation (minus Javadocs) that is available, but I'm still having some difficulty understanding exactly how to set it up.

In an attempt to implement in stages, I've modified my shiro.ini as follows with the intention of simply using SHA-256 hashes:

[main]
dataSource = org.apache.shiro.jndi.JndiObjectFactory
dataSource.resourceName = jdbc/Communicator_dev
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource = $dataSource
dataSource.resourceRef = true;

jdbcRealm.authenticationQuery = select password from account where site_id = ?
jdbcRealm.userRolesQuery = select user_role from web_roles where site_id = ?

# From https://stackoverflow.com/questions/20742666/shiro-with-jdbc-and-hashed-passwords.
#
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
#configure the passwordService to use the settings you desire
#...
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService
#...
# Finally, set the matcher on a realm that requires password matching for account authentication:
jdbcRealm.credentialsMatcher = $passwordMatcher

The actual login logic is programmatic in a page backing bean. Here's the simple test source I'm currently using:

    // Create auth token
    UsernamePasswordToken token = new UsernamePasswordToken(this.siteID, this.password);
    // Get the current subject
    Subject currentUser = SecurityUtils.getSubject();
    // Attempt to login
    try {
        currentUser.login(token);
    } catch (AuthenticationException e) {
        System.out.println("Invalid creds.");
        return "";
    }
    return "authenticated.xhtml?faces-redirect=true";

This code works perfectly with plaintext passwords stored in my RDBMS, but now that I've hashed them, It's failing.

From my understanding of the framework, I believe the problem lies with the AuthenticationToken. I know that I need to use a different token to ultimately implement the Salted Hashes stored in my RDBMS, but I'm confused on how to proceed.

(1) I don't want to reinvent the wheel. Does Shiro have something that does this natively? I've checked out Les' links to PasswordMatcher and PasswordService (from link shiro with jdbc and hashed passwords) but this still isn't clear. Do I need to sub-classingPasswordMatcher?

(2) An architecture question: Who actually calls the doCredentialsMatch(..) method? Is it the Realm during the execution of the login(...) method?

(3) The AuthenticationInfo parameter of the doCredentialsMap(...) method .. Is that supplied by the Realm? Since Realms encapsulate the actual security data, is this an object created from, in my case, the SQL queries that return the password from the RDBMS?

Thank you very much for your time! I'm hoping to be able to contribute to the documentation when I get my head wrapped around it all.

Community
  • 1
  • 1
Naitouk
  • 111
  • 7

1 Answers1

1

Item 1: I suspect you may be running into this issue involving the "salt style" parameter of the JdbcRealm which defaults to "NO_SALT". This causes hashing to work but if you're adding a salt to your password the realm will be unable to properly match them.

Here are your steps afterwards:

The default query for a COLUMN based salt style is as follows, "select password, password_salt from users where username = ?". If you cannot use that structure you need to provide a new query via your 'shiro.ini' with a similar structure.

jdbcRealm.authenticationQuery=select password, salt_column_here from users where username = ?

Here is a related question.

Item 2: Yes, the realm calls the doCredentialsMatch(..) method.

Item 3: Yes, the realm supplies the AuthenticationInfo to the doCredentialsMatch(..) method.

Community
  • 1
  • 1
justin.hughey
  • 1,246
  • 15
  • 16
  • Still quite confused, though your link for salt style certainly helps. Once the salt style is set to "COLUMN," how does one specify the column that actually contains the salt value? – Naitouk Nov 29 '14 at 05:29
  • Hi Naitouk, I didn't realize you had asked a follow-up question. If you look at the example query the select clause has two columns, "password" and "salt_column_here". The second column is what maps your database salt column so that Shiro can find it. – justin.hughey Apr 16 '15 at 13:24