Using JDBCRealm to authenticate user with Shiro
Asked Answered
D

1

11

I am trying to authenticate a servlet running within Tomcat 6 using Shiro.

I have the following shiro.ini file:

[main]
ps = org.apache.shiro.authc.credential.DefaultPasswordService
pm = org.apache.shiro.authc.credential.PasswordMatcher
pm.passwordService = $ps

aa = org.apache.shiro.authc.credential.AllowAllCredentialsMatcher
sm = org.apache.shiro.authc.credential.SimpleCredentialsMatcher

jof = org.apache.shiro.jndi.JndiObjectFactory
jof.resourceName = jdbc/UserDB
jof.requiredType = javax.sql.DataSource
jof.resourceRef = true

realm = org.apache.shiro.realm.jdbc.JdbcRealm
realm.permissionsLookupEnabled = true
realm.credentialsMatcher = $pm
; Note factories are automatically invoked via getInstance(),
;   see org.apache.shiro.authc.config.ReflectionBuilder::resolveReference
realm.dataSource = $jof

securityManager.realms = $realm

[urls]
/rest/** = authcBasic
/prot/** = authcBasic

And the following in my database:

mysql> select * from users;
+----------+------------------+----------+----------------------------------------------+--------------------------+
| username | email            | verified | password                                     | password_salt            |
+----------+------------------+----------+----------------------------------------------+--------------------------+
| admin    | a.muys@********* |        1 | ojSiTecNwRF0MunGRvz3DRSgP7sMF9EAR77Ol/2IAY8= | eHp9XedrIUa5sECfOb+KOA== |
+----------+------------------+----------+----------------------------------------------+--------------------------+
1 row in set (0.00 sec)

If I use the SimpleCredentialsManager it authenticates fine against a plaintext password in the users table. Trying to use the PasswordMatcher has been extremely frustrating.

The password and password_salt were obtained via the shiro-tools Hasher utility.

When I try to authenticate against a basic HelloWorld servlet I use for testing (path=rest/hello, context=/ws), I get the following in the logs:

15:35:38.667 [http-8080-2] TRACE org.apache.shiro.util.ClassUtils - Unable to load clazz named [ojSiTecNwRF0MunGRvz3DRSgP7sMF9EAR77Ol/2IAY8=] from class loader [WebappClassLoader
  context: /ws
  delegate: false
  repositories:
    /WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@79ddd026
]

(Full log at https://gist.github.com/recurse/5915693 )

It appears to be trying to load my hashed password as a classname. Is this a bug, or a configuration error on my part? If it is a bug, how can I work around it? If it is a configuration error, what am I missing?

Disc answered 3/7, 2013 at 5:43 Comment(3)
just what i was looking for, thank you, btw did you follow any tutorial for this kind of set up ? i was trying to integrate my jdbc realm with sha hashes and couldnt find any relevant tutorials.Jolee
No. I read the documentation on the Shiro site to understand the basic structure of the API; then, I checked out the code and reverse engineered the JDBC configuration.Disc
where in shiro.ini does it specify that you use the users table?Lamartine
F
10

First, thanks for providing a lot of information for this question - it makes providing an answer a lot easier.

By looking at your sample database row list, it does not appear that you are storing the output that the PasswordService expects when performing a hashed password comparison. For example:

$ java -jar ~/.m2/repository/org/apache/shiro/tools/shiro-tools-hasher/1.2.2/shiro-tools-hasher-1.2.2-cli.jar -p
Password to hash:
Password to hash (confirm):
$shiro1$SHA-256$500000$uxaA2ngfdxdXpvSWzpuFdg==$hOJZc+3+bFYYRgVn5wkbQL+m/FseeqDtoM5mOiwAR3E=

The String that starts with $shiro1$ is what you would save to the password column in the database. There is no need for a separate salt column as all the information Shiro needs is in the $shiro1$... String.

The DefaultPasswordService uses the same default configuration parameters (SHA-256, 500,000 iterations, etc) so if you use the Hasher CLI tool as I've shown above (no extra hash algorithm config), you don't need to customize the DefaultPasswordService POJO any further. However, if you change the hashing parameters on the CLI, you need to ensure that the same parameters are configured on the DefaultPasswordService bean (and/or its internal HashingService).

If you are still in testing and can change your DB schema, I'd recommend doing that now to have a single password field that stores the $shiro1$... string. Then you use the PasswordService as documented here under Usage:

http://shiro.apache.org/static/current/apidocs/org/apache/shiro/authc/credential/PasswordService.html

Finsen answered 3/7, 2013 at 16:8 Comment(1)
Configuring this in shiro.ini is described on the Usage page linked by @LesHazlewood. For configuration done in Java see here: https://mcmap.net/q/1019048/-using-shiro-39-s-passwordmatcher-with-a-custom-realmDisillusion

© 2022 - 2024 — McMap. All rights reserved.