问题描述
我一直在探索使用 Zeppelin 的 Apache Shiro,到目前为止已经能够使用 JdbcRealm 进行身份验证,但不顺利的一件事是以纯文本形式提供数据源密码。
有没有办法避免这种情况?
我的 shiro.ini 看起来像:
[main]
dataSource = org.postgresql.ds.PGPoolingDataSource
dataSource.serverName = localhost
dataSource.databaseName = dp
dataSource.user = dp_test
dataSource.password = Password123
ps = org.apache.shiro.authc.credential.DefaultPasswordService
pm = org.apache.shiro.authc.credential.PasswordMatcher
pm.passwordService = $ps
jdbcRealm = org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealmCredentialsMatcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
jdbcRealm.dataSource = $dataSource
jdbcRealm.credentialsMatcher = $pm
shiro.loginUrl = /api/login
[roles]
admin = *
[urls]
/** = authc
有没有办法避免以纯文本形式提供数据源密码
dataSource.password = Password123
?
想给出类似的东西:
$shiro1$SHA-256$500000$YdUEhfDpsx9KLGeyshFegQ==$m+4wcq4bJZo1HqDAGECx50LcEkRZI0zCyq99gtRqZDk=
解决方法
是的,有办法,但由于 shiro 需要知道密码的性质,密码仍然存在于某处。
为什么散列不起作用
你发布了
类似:$shiro1$SHA-256[…]
这是一个散列,因此它是不可逆的。 shiro 无法使用此字符串登录数据源。
容器管理的数据源
此时我可以推荐的最佳方法是拥有一个容器管理的资源。在这种情况下,容器指的是(Web)应用服务器,例如 tomcat、OpenLiberty 或 Wildfly。
对于您的用例,请尝试查看以下内容:
- 扩展
org.apache.shiro.realm.jdbc.JdbcRealm
或AuthorizingRealm
- 将 JPA API 添加到您的模块并注入持久性上下文,如下所示:
@PersistenceContext
EntityManager entityManager;
- 覆盖方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
...改为从您的托管数据源加载。
这种方法的缺点:
您刚刚将数据源登录委托给您的容器/应用程序服务器。服务器仍然面临同样的问题。例如。使用 OpenLiberty,您仍然需要在某处存储加密(未散列)密码的主密钥,and thus liberty will do exactly this。
使用另一个配置源
除了使用 shiro.ini
文件,您还可以编写自己的 environment loader。您可以从受 IP 限制的网络服务或加密硬件设备请求文件。
永远的目标:限制环境
您应该始终限制环境。 例如。创建一个可以安装但不能运行您的应用程序并且无法读取日志的用户(称为 setup-user 左右)。 创建另一个可以启动应用程序、读取但不能修改配置文件和写入日志的用户,称为运行用户。
限制该系统上所有其他用户访问配置和日志。
参与
如果您有其他需求,欢迎在 shiro mailing lists 上讨论其他解决方案。