【发布时间】:2014-12-29 14:56:22
【问题描述】:
我正在尝试使用 Shiro 对我正在构建的 JSF Web 应用程序进行身份验证和授权。不幸的是,我仍然难以理解它们是如何组合在一起的。
我已经成功(100% 使用 shiro.ini 文件)将身份验证配置回用于存储测试凭据集的 JDBC 领域。当凭据以明文形式存储时,它对我来说非常有效。
我的最终目标是统一 MySQL 数据库中的现有凭据集。密码存储为 SHA-256 加盐哈希。我花了一整天的时间阅读可用的文档(减去 Javadocs),但我仍然难以理解如何设置它。
为了尝试分阶段实施,我将 shiro.ini 修改如下,目的是简单地使用 SHA-256 哈希:
[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
实际的登录逻辑是在页面支持 bean 中编程的。这是我目前正在使用的简单测试源:
// 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";
这段代码与存储在我的 RDBMS 中的纯文本密码完美配合,但现在我已经对它们进行了哈希处理,它失败了。
根据我对框架的理解,我认为问题出在 AuthenticationToken 上。我知道我需要使用不同的令牌来最终实现存储在我的 RDBMS 中的盐渍哈希,但我对如何继续感到困惑。
(1) 我不想重新发明轮子。 Shiro 是否有一些本机可以做到这一点的东西?我已经查看了 Les 到 PasswordMatcher 和 PasswordService 的链接(来自链接 shiro with jdbc and hashed passwords),但这仍然不清楚。我需要对PasswordMatcher 进行子类化吗?
(2) 一个架构问题:谁真正调用了 doCredentialsMatch(..) 方法?在 login(...) 方法执行期间是 Realm 吗?
(3) doCredentialsMap(...) 方法的 AuthenticationInfo 参数.. 是由 Realm 提供的吗?由于 Realms 封装了实际的安全数据,在我的例子中,这是一个从 RDBMS 返回密码的 SQL 查询创建的对象吗?
非常感谢您的宝贵时间!当我全神贯注时,我希望能够为文档做出贡献。
【问题讨论】: