2017-07-06 2 views
1

J'utilise le code suivant pour créer un serveur JMX personnalisé avec TLS et JMXMP en suivant la documentation Oracle. Cela fonctionne bien et je peux me connecter au serveur sans problème, cependant je voudrais ajouter "USER" et "PASSWORD" à l'authentification, cependant en spécifiant le "password.properties" et le "access.properties" ne fonctionne pas, JMX semble ignorer ces deux options. Quelqu'un peut-il faire la lumière sur la façon correcte de configurer USER et PASSWORD et corriger ce problème? MerciComment s'authentifier avec un utilisateur et un mot de passe en utilisant le serveur JMX personnalisé en utilisant TLS et JMXMP

 private JMXServiceURL url() { 
     final String url = String.format("service:jmx:jmxmp://%s:%s", host(), port()); 
     try { 

      return new JMXServiceURL(url); 

     } catch(Throwable exception) { 
      throw new RuntimeException(String.format("Failed to create JMX Service URL: %s", url), exception); 
     } 
    } 

    private Map<String, Object> env() { 
     final Map<String, Object> env = new LinkedHashMap<String, Object>(); 


     try { 

      String keystore = "jmx.keystore"; 

      char keystorepass[] = "12345678".toCharArray(); 
      char keypassword[] = "12345678".toCharArray(); 

      KeyStore ks = KeyStore.getInstance("JKS"); 
      ks.load(new FileInputStream(keystore), keystorepass); 
      KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 

      kmf.init(ks, keypassword); 
      SSLContext ctx = SSLContext.getInstance("TLSv1"); 
      ctx.init(kmf.getKeyManagers(), null, null); 
      SSLSocketFactory ssf = ctx.getSocketFactory(); 

      env.put("jmx.remote.profiles", "TLS"); 
      env.put("jmx.remote.tls.socket.factory", ssf); 
      env.put("jmx.remote.tls.enabled.protocols", "TLSv1"); 
      env.put("jmx.remote.tls.enabled.cipher.suites","SSL_RSA_WITH_NULL_MD5"); 


      env.put("jmx.remote.x.password.file", "password.properties"); 
      env.put("jmx.remote.x.access.file","access.properties"); 


     } catch (Exception e) { 
      e.printStackTrace(); 
     } 


     return env; 
    } 

    private MBeanServer server() { 
     return ManagementFactory.getPlatformMBeanServer(); 
    } 

    private JMXConnectorServer connector() { 
     try { 

      ServerProvider.class.getName(); 
      return JMXConnectorServerFactory.newJMXConnectorServer(url(), env(), server()); 

     }catch(Throwable exception) { 
      throw new RuntimeException("Failed to create JMX connector server factory", exception); 
     } 
    } 

Répondre

1

J'a finalement pu configurer l'utilisateur supplémentaire et mot de passe pour la connexion JMXMP avec le code suivant à partir de la documentation Oracle

MBeanServer mbs = MBeanServerFactory.createMBeanServer(); 
Security.addProvider(new com.sun.jdmk.security.sasl.Provider()); 

HashMap env = new HashMap(); 
env.put("jmx.remote.profiles", "TLS SASL/PLAIN"); 
env.put("jmx.remote.sasl.callback.handler", 
    new PropertiesFileCallbackHandler("password.properties")); 
env.put("jmx.remote.x.access.file",access.properties"); 

JMXServiceURL url = new JMXServiceURL("jmxmp", null, 5555); 
JMXConnectorServer cs = 
    JMXConnectorServerFactory.newJMXConnectorServer(url, 
                env, 
                mbs); 
cs.start(); 

Je mis en œuvre simple CallBackHandler pour la validation du mot de passe

public final class PropertiesFileCallbackHandler 
    implements CallbackHandler { 

    private Properties pwDb; 

    /** 
    * Contents of files are in the Properties file format. 
    * 
    * @param pwFile name of file containing name/password 
    */ 
    public PropertiesFileCallbackHandler(String pwFile) throws IOException { 

     if (pwFile != null) { 

      File file = new File(pwFile); 

      if(file.exists()) { 
       pwDb = new Properties(); 
       pwDb.load(new FileInputStream(file)); 
      } else { 
       throw new IOException("File " + pwFile + " not found"); 
      } 
     } 
    } 

    public void handle(Callback[] callbacks) 
     throws UnsupportedCallbackException { 

     AuthorizeCallback acb = null; 
     AuthenticateCallback aucb = null; 

     for (int i = 0; i < callbacks.length; i++) {  
      if (callbacks[i] instanceof AuthorizeCallback) { 
       acb = (AuthorizeCallback) callbacks[i]; 
      } else if (callbacks[i] instanceof AuthenticateCallback) { 
       aucb = (AuthenticateCallback)callbacks[i]; 
      } else { 
       throw new UnsupportedCallbackException(callbacks[i]); 
      } 
     } 

     // Process retrieval of password; can get password if 
     // username is available 
     if (aucb != null) { 
      String username = aucb.getAuthenticationID(); 
      String password = new String(aucb.getPassword()); 
      String pw = pwDb.getProperty(username); 

      if (pw != null) { 
       if(pw.equals(password)){ 
        aucb.setAuthenticated(true); 
       } 
      } 
     } 

     // Check for authorization 
     if (acb != null) { 
      String authid = acb.getAuthenticationID(); 
      String authzid = acb.getAuthorizationID(); 
      if (authid.equals(authzid)) { 
       // Self is always authorized 
       acb.setAuthorized(true); 
      } 
     } 
    } 
} 
+0

Comment êtes-vous arrivé à cela? –

+0

Avez-vous dû configurer le client de la même manière? – Adam

+0

Oui, vous devez configurer le client pour qu'il utilise également ce type d'authentification –