【发布时间】:2013-09-01 16:35:16
【问题描述】:
在我正在构建的应用程序中,我们直接使用 Java 6 EE 和 JBoss(没有 Spring 等),以及 JPA/Hibernate、JSF、CDI 和 EJB。
我没有找到很多好的通用安全解决方案(欢迎提出建议),但我发现最好的选择是 Apache Shiro。
但是,这似乎有许多缺点。您可以在Balus C's 网站上阅读其中的一些内容:
http://balusc.blogspot.com/2013/01/apache-shiro-is-it-ready-for-java-ee-6.html
但是我偶然发现了另一个大问题,已经提到 here 关于依赖注入和代理。
基本上,我有一个写得很好的基于 JPA 的 UserDAO,它提供了身份验证所需的一切。我的数据库在 persistence.xml 和 mydatabase-ds.xml(用于 JBoss)中整齐地配置。
再次复制所有这些配置信息并将用户表查询添加到 shiro.ini 似乎很愚蠢。所以这就是为什么我选择编写自己的 Realm 而不是使用 JdbcRealm。
我对此的第一次尝试是继承 AuthorizingRealm...类似于:
@Stateless
public MyAppRealm extends AuthorizingRealm {
@Inject private UserAccess userAccess;
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
User user = userAccess.getUserByEmail(userPassToken.getUsername());
if (user == null) {
return null;
}
AuthenticationInfo info = new SimpleAuthenticationInfo();
// set data in AuthenticationInfo based on data from the user object
return info;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO
return null;
}
}
所以这很糟糕,因为无法代理 MyAppRealm,因为在类层次结构的父类中有一个 final init() 方法。
我的第二次尝试是让 MyAppRealm 实现所有需要的接口,并将它们委托给 AuthorizingRealm 实例。我不喜欢这个,但不妨试一试。
这让我更进一步,webapp 启动了,但仍然不足。原因是在配置文件 shiro.ini 中,我为我的领域指定了类:
myAppRealm = com.myapp.MyAppRealm
这几乎告诉我 Shiro 将负责创建 MyAppRealm 实例。因此它不会由 CDI 管理,因此不会被注入,这正是我所看到的。
我已经看到了这个 SO answer,但我不明白它是如何工作的,因为 AuthorizingRealm 的子类将再次继承最终的 init() 方法,这意味着子类不能被代理。
有什么想法可以解决这个问题吗?
【问题讨论】:
标签: jakarta-ee cdi shiro