我已经研究 JMX 一段时间了,但我被困住了。
我有一个通过 JMX 向远程客户端公开一些功能的应用程序,尽管现有的安全功能对于大多数情况下可能就足够了,我的应用程序使用 Apache Shiro 框架作为安全后端。
我的问题是我不知道如何在服务器端收集客户端数据。Shiro 需要一种识别客户端(主题)的方法,通常执行线程与主题相关联,但在线 JMX 文档并没有提供有关远程 JMX 线程模型的太多线索。
我如何将客户端与线程相关联,或者有没有办法在交互的 MBean 中检索客户端数据?
经过研究和尝试不同的技术;有两个获胜者:
1- 称为 ClientContext 的新特性将成为 Java 7 的一部分:Java 7 尚未完成,ClientContext 将破坏向后兼容性。
2- 将 Shiro 主题附加到 AccessControlContext:这是我选择的解决方案,Shiro 的默认主题检索机制不考虑 Java 的访问控制上下文。我很久以前进行了一次测试来测试它,但它没有用。现在我知道为什么了:默认情况下,SecurityUtils.getSubject() 调用会将检索到的 Subject 附加到当前调用线程,但是这种方法是无用的,因为线程可以在客户端之间共享。但是 AccessControlContext 要强大得多,看起来 JMX 可以很好地配合它;您的访问控制上下文(在 JMXAuthenticator 登录期间经过身份验证)可以从 MBeanServerForwarder 甚至在您的 MBean 中访问。我用多个客户检索他们的委托人对此进行了测试,它很有效。
编辑:我如何将 Shiro 主题附加到当前的 AccessControlContext?
1- 使用构建器类 Subject.Builder 创建一个未附加的 Shiro 主题。
2-对用户进行身份验证(使用Shiro主题的登录方法等)
3- 创建一个可变的 JAAS 主题,其中包含一个包含 Shiro 主题作为私有凭证的单例集。
4- 为底层 Java 安全系统提供 JAAS 主题(例如,在 JMXAuthenticator 的身份验证方法中返回主题)
可以创建一个帮助类来简化这种方法。当您需要代表 Shiro 主题执行操作时(用于授权等),从 AccessControlContext 获取它并使用 Subject.execute... 方法之一。这可以在代理或转发器(如 MBeanServerForwarder)内执行。