使用 JDBCRealm 通过 Shiro 对用户进行身份验证

Posted

技术标签:

【中文标题】使用 JDBCRealm 通过 Shiro 对用户进行身份验证【英文标题】:Using JDBCRealm to authenticate user with Shiro 【发布时间】:2013-06-30 16:51:25 【问题描述】:

我正在尝试使用 Shiro 验证在 Tomcat 6 中运行的 servlet。

我有以下 shiro.ini 文件:

[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

我的数据库中有以下内容:

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)

如果我使用SimpleCredentialsManager,它会根据用户表中的明文密码进行身份验证。尝试使用PasswordMatcher 非常令人沮丧。

password 和 password_salt 是通过 shiro-tools Hasher 实用程序获得的。

当我尝试针对用于测试的基本 HelloWorld servlet (path=rest/hello, context=/ws) 进行身份验证时,我在日志中得到以下信息:

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
]

(完整日志https://gist.github.com/recurse/5915693)

它似乎试图将我的散列密码加载为类名。这是一个错误,还是我的配置错误?如果它是一个错误,我该如何解决它?如果是配置错误,我错过了什么?

【问题讨论】:

正是我想要的,谢谢,顺便说一句,您是否按照任何教程进行了这种设置?我试图将我的 jdbc 领域与 sha 哈希集成,但找不到任何相关教程。 没有。我阅读了 Shiro 网站上的文档以了解 API 的基本结构;然后,我检查了代码并对 JDBC 配置进行了逆向工程。 shiro.ini 的哪个位置指定您使用users 表? 【参考方案1】:

首先,感谢您为这个问题提供了大量信息 - 它使提供答案变得更加容易。

通过查看您的示例数据库行列表,您似乎没有存储 PasswordService 在执行散列密码比较时期望的输出。例如:

$ 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=

$shiro1$ 开头的字符串是您将保存到数据库中password 列的内容。不需要单独的盐列,因为 Shiro 需要的所有信息都在 $shiro1$... 字符串中。

DefaultPasswordService 使用相同的默认配置参数(SHA-256、500,000 次迭代等),因此如果您使用上面显示的 Hasher CLI 工具(没有额外的哈希算法配置),则不需要进一步自定义DefaultPasswordService POJO。但是,如果您在 CLI 上更改哈希参数,则需要确保在 DefaultPasswordService bean(和/或其内部 HashingService)上配置相同的参数。

如果您仍在测试中并且可以更改您的数据库架构,我建议您现在这样做,以便拥有一个存储$shiro1$... 字符串的密码字段。然后使用 Usage 下记录的 PasswordService:

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

【讨论】:

在@LesHazlewood 链接的Usage 页面上描述了在shiro.ini 中的配置。对于用 Java 完成的配置,请参见此处:***.com/a/45225711/2969332

以上是关于使用 JDBCRealm 通过 Shiro 对用户进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Shiro JdbcRealm 授权的表模式?

shiro框架学习-4- Shiro内置JdbcRealm

Shiro Spring JDBCRealm 身份验证和授权

shiro学习笔记_0300_jdbcRealm和认证策略

shiro,使用第三方jdbcRealm连接数据库操作

如何获取/设置 JdbcRealm 的盐