I'm working with a JSF2
application where I'd like to use Apache Shiro
. I have it up-and-running though I don't know how to specify the number of Hash
iterations to be used.
shiro.ini
[main]
user = com.nivis.filter.FacesAjaxAwareUserFilter
shiro.loginUrl = /faces/login.xhtml
user.loginUrl = /faces/login.xhtml
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.authenticationQuery = SELECT password FROM app_user WHERE username = ?
dataSource = org.apache.shiro.jndi.JndiObjectFactory
dataSource.requiredType = javax.sql.DataSource
dataSource.resourceName = JNDImysql
jdbcRealm.dataSource = $dataSource
securityManager.realms = $jdbcRealm
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordMatcher.passwordService = $passwordService
jdbcRealm.credentialsMatcher = $passwordMatcher
[urls]
/faces/login.xhtml = user
/faces/index.xhtml = user
/faces/app/** = user
It does work to get the password hashed even though I do not explicitly specify a hash service
. I saw an example using:
hashService = org.apache.shiro.crypto.hash.DefaultHashService
hashService.hashIterations = 10000
hashService.hashAlgorithmName = SHA-256
passwordService.hashService = $hashService
Which I tried to use, although it didn't make any difference. As it seems to be enough to use only the PasswordService
to get the password hashed, I'd like to know if there's a way of specifying how many hash iterations to use?
You can try to do it like this:
# Configure Data Source --> see web.xml for full configuration
dataSource = org.apache.shiro.jndi.JndiObjectFactory
dataSource.resourceName = <resource name>
dataSource.resourceRef = true
# Create JDBC-Realm to connect to the Datasource and set the authenticationQuery
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource = $dataSource
jdbcRealm.authenticationQuery = SELECT password FROM <user table> WHERE email = ?
# Configure JDBC realm password hashing.
hashService = org.apache.shiro.crypto.hash.DefaultHashService
hashService.hashIterations = <number of iterations>
hashService.hashAlgorithmName = SHA-256
hashService.generatePublicSalt = true
# privateSalt needs to be base64-encoded in shiro.ini but not in the Java code!
hashService.privateSalt = <base64-encoded Salt string>
passwordMatcher = org.apache.shiro.authc.credential.PasswordMatcher
passwordService = org.apache.shiro.authc.credential.DefaultPasswordService
passwordService.hashService = $hashService
passwordMatcher.passwordService = $passwordService
jdbcRealm.credentialsMatcher = $passwordMatcher
Note: this example also uses a private salt. To add more security against passwords being calculated using rainbow tables / brute force attacks, I strongly recommend using a salt. The above example code might not be the best way to handle salting, but it works fine. Also take care that a Salt needs to be base64-encoded in the shiro.ini but not in the java code.