Рубрики
Без рубрики

Пример клиента Java JMX – Аутентификация JMX

Пример клиента JMX. Клиент Java JMX, аутентификация на основе ролей JMX, удаленный доступ jmx, пароль, JMXServiceURL, jmxConnector, вызов MBeanServerConnection

Автор оригинала: Pankaj Kumar.

В последнем уроке мы узнали об основах JMX и о том, как мы можем использовать JConsole для управления MBeans . Сегодня мы рассмотрим пример клиента java jmx и проверку подлинности на основе ролей с помощью файлов конфигурации.

Клиент Java JMX

Хотя JConsole предоставляет графическое представление, но оно требует человеческих усилий для работы с MBean и не подходит там, где вы хотите периодически вызывать некоторые функции MBean. Например, у вас есть MBean, который предоставляет текущее состояние приложения, и вы хотите вызывать его для проверки состояния каждые 10 минут. В этом случае очень полезно иметь программу java, которая может работать как клиент JMX для подключения к серверу JMX MBean и вызова операций MBean.

Пример клиента JMX

Здесь мы напишем java-программу, которая может подключаться к серверу MBean и создавать прокси-приложение для вызова операций MBean. Я буду использовать приложение MBean, созданное в учебнике JMX, и использовать нашу клиентскую программу для подключения к MBean. Позже мы проверим, как обеспечить безопасность нашего сервера MBean с помощью файлов конфигурации JMX для доступа на основе ролей и как мы можем использовать учетные данные в клиенте JMX для подключения к серверу MBean с правильной ролью.

Прежде чем писать клиентское приложение JMX, нам нужно знать порт, на котором работает сервер MBean. Также для начала мы отключим всю аутентификацию. Мы можем сделать все это, передав правильные параметры java.

Поэтому я начну свой MBean со следующей команды. Обратите внимание на параметры java, указанные для порта сервера MBean, и отключение SSL и аутентификации.

pankaj@JD:~/CODE/JavaProject/bin$ java -cp . -Dcom.sun.management.jmxremote.port=1234 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false com.journaldev.jmx.SystemConfigManagement
Thread Count=10:::Schema Name=default
Thread Count=10:::Schema Name=default
Thread Count=10:::Schema Name=default
...

URL-АДРЕС JMX

Чтобы клиентское приложение получило прокси-сервер MBean, сначала нам нужно создать JMXServiceURL , передав хост и порт RMI.

JMXServiceURL url =
            new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + HOST + ":" + PORT + "/jmxrmi");

После этого мы должны получить экземпляр JMX Connector , используя его заводской класс.

JMXConnector jmxConnector = JMXConnectorFactory.connect(url);

После этого мы получаем MBeanServerConnection из экземпляра соединителя JMX.

MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();

После этого мы получаем экземпляр прокси-сервера MBean с помощью MBeanServerInvocationHandler .

//ObjectName should be same as your MBean name
ObjectName mbeanName = new ObjectName("com.journaldev.jmx:type=SystemConfig");

//Get MBean proxy instance that will be used to make calls to registered MBean
SystemConfigMBean mbeanProxy =
    (SystemConfigMBean) MBeanServerInvocationHandler.newProxyInstance(
        mbeanServerConnection, mbeanName, SystemConfigMBean.class, true);

Как только мы получим экземпляр прокси-сервера, мы сможем вызвать любую операцию, предоставленную MBean.

Пример клиентской программы Java JMX

Вот полная клиентская программа JMX, которая подключается к серверу MBean, получает экземпляр прокси-сервера MBean конфигурации системы и вызывает открытые методы.

package com.journaldev.jmx;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class SystemConfigClient {

    public static final String HOST = "localhost";
    public static final String PORT = "1234";

    public static void main(String[] args) throws IOException, MalformedObjectNameException {
        JMXServiceURL url =
            new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + HOST + ":" + PORT + "/jmxrmi");
        
        JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
        MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();
        //ObjectName should be same as your MBean name
        ObjectName mbeanName = new ObjectName("com.journaldev.jmx:type=SystemConfig");

        //Get MBean proxy instance that will be used to make calls to registered MBean
        SystemConfigMBean mbeanProxy =
            (SystemConfigMBean) MBeanServerInvocationHandler.newProxyInstance(
                mbeanServerConnection, mbeanName, SystemConfigMBean.class, true);

        //let's make some calls to mbean through proxy and see the results.
        System.out.println("Current SystemConfig::" + mbeanProxy.doConfig());
        
        mbeanProxy.setSchemaName("NewSchema");
        mbeanProxy.setThreadCount(5);
        
        System.out.println("New SystemConfig::" + mbeanProxy.doConfig());
        
        //let's terminate the mbean by making thread count as 0
        mbeanProxy.setThreadCount(0);

        //close the connection
        jmxConnector.close();
    }
}

Перед запуском клиентского приложения убедитесь, что наше приложение MBean запущено с помощью команды, указанной в начале сообщения. Когда мы выполним клиентское приложение, оно выведет следующее в консоль.

Current SystemConfig::No of Threads=10 and DB Schema Name=default
New SystemConfig::No of Threads=5 and DB Schema Name=NewSchema

Если вы проверите терминал, в котором запущено наше приложение MBean, вы найдете следующий вывод до завершения программы.

Thread Count=10:::Schema Name=default
Thread Count=10:::Schema Name=default
Thread Count=0:::Schema Name=NewSchema

Итак, теперь мы знаем, как написать клиентскую программу JMX, которая может подключаться к удаленному серверу MBean и создавать прокси-сервер MBean для использования атрибутов и операций, предоставляемых MBean.

Аутентификация на основе ролей JMX

Давайте начнем настраивать наш MBean для проверки подлинности на основе ролей. Для этого нам нужно создать три файла.

  1. Файл доступа JMX : Этот файл содержит роли и доступ, связанные с ролями. Типы доступа: только для чтения или запись для чтения . Для нашей цели создайте jmxremote.access файл со следующим содержимым.

    Файл доступа JMX

    : Этот файл содержит роли и доступ, связанные с ролями. Типы доступа:

    только для чтения

  2. или запись для чтения

    . Для нашей цели создайте jmxremote.access файл со следующим содержимым.

    Таким образом, роль-это "моя роль", и у нее есть доступ для чтения и записи к Средствам.

    Файл пароля JMX : Этот файл содержит пароль различных ролей, которые у нас есть, пароль является открытым текстом, поэтому Java добавляет ограничение, согласно которому только владелец приложения должен иметь доступ к файлу для чтения и записи. Создайте файл

  3. jmxremote.password со следующим содержимым. Создайте файл jmxremote.password

    со следующим содержимым.

    После создания файла измените разрешение с помощью команды

Как только все необходимые файлы будут собраны, мы запустим наше приложение JMX MBean со следующей командой.

java -cp . -Dcom.sun.management.config.file=management.properties com.journaldev.jmx.SystemConfigManagement

Теперь, если вы попытаетесь запустить наше клиентское приложение JMX, оно выдаст следующее исключение.

Exception in thread "main" java.lang.SecurityException: Authentication failed! Credentials required
	at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticationFailure(JMXPluggableAuthenticator.java:211)
	at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticate(JMXPluggableAuthenticator.java:163)
	at sun.management.jmxremote.ConnectorBootstrap$AccessFileCheckerAuthenticator.authenticate(ConnectorBootstrap.java:219)
	at javax.management.remote.rmi.RMIServerImpl.doNewClient(RMIServerImpl.java:232)

Сообщение об исключении ясно показывает, что нам необходимо предоставить учетные данные для доступа к JMX MBean. Чтобы предоставить учетные данные, нам необходимо добавить следующий код в нашу клиентскую программу.

//for passing credentials for password 
Map env = new HashMap<>();
String[] credentials = {"myrole", "MYP@SSWORD"};
env.put(JMXConnector.CREDENTIALS, credentials);
        
JMXConnector jmxConnector = JMXConnectorFactory.connect(url, env);

Обратите внимание, что конструктор изменен для предоставления учетных данных при подключении к серверу JMX MBean. Теперь программа будет работать нормально и выдавать те же результаты, что и ранее.

Это все для примера клиента Java JMX и проверки подлинности JMX для доступа на основе ролей.