JMX身份验证 - 基于角色的MBean操作

时间:2014-11-28 16:10:48

标签: java authentication jmx mbeans

我已经通过RMI实现了JMXAuthenticator JMX身份验证,但我不确定如何创建角色以允许readonly / readwrite访问级别。例如,在JMXAuthenticator.authenticate中我有自定义身份验证逻辑,并希望这可以确定访问角色。我尝试过以下操作,但在JConsole中执行操作时没有任何区别:

@Override
public Subject authenticate(Object credentials) {
    Subject subject = new Subject();
    JMXPrincipal p;

    //...my logic
    String accessLevel = myCustomLogic();
    if (accessLevel.equals("admin")) {
        p = new JMXPrincipal("adminrole");
    } else {
        p = new JMXPrincipal("basicrole");
    }

    subject.getPrincipals().add(p);
    return subject;
}

然后我创建了一个包含

的访问文件jmxaccess.properties
adminuser readwrite
basicuser readonly

jmx.management.properties包含com.sun.management.jmxremote.access.file=PATH TO ACCESS FILE,我使用-Dcom.sun.management.config.file=PATH TO jmx.management.properties运行应用程序。

然而,当我通过JConsole连接并作为基本用户(只读访问)进行身份验证时,我可以访问bean上的setter。我通过完整的service:jmx:rmi:...网址进行连接。

所以我的问题是

  • 我是否需要为我的bean中的setter注释/执行任何操作,以将它们指定为仅对管理员用户可见?
  • 我是否未正确构建Subject JMXAuthenticator返回的对象?
  • 缺少任何其他配置/设置?

由于

编辑我的MBean只是一个基本的POJO,其私有字段包含公共getter和setter以及另一个公共方法。

1 个答案:

答案 0 :(得分:1)

找到答案:需要通过InvocationHandler接口实现自定义调用处理程序。这会在服务器调用到达bean之前拦截它们。在authenticate方法中,您需要检查主体

AccessControlContext acc = AccessController.getContext();
Subject subject = Subject.getSubject(acc);
Set principals = subject.getPrincipals(JMXPrincipal.class);
if(principals != null && !principals.isEmpty()) {
    Principal principal = (Principal)principals.iterator().next();
    //your checks
}

我扩展了JMXPrincipal(每个访问级别一个扩展)并将其分配给上面的Authenticator中的Subject,然后在IH中检索主体后,我可以通过instanceof检查类型并允许操作继续或抛出SecurityException