2017-07-06 84 views
1

我正在使用以下代碼在Oracle文檔之後使用TLS和JMXMP創建自定義JMX服務器。它運行良好,我可以連接到服務器沒有問題,但是我想添加「用戶」和「密碼」的身份驗證,但指定「password.properties」和「access.properties」不起作用, JMX似乎忽略了這兩個選項。有人可以通過正確的方式瞭解如何配置USER和PASSWORD並糾正這個問題嗎?由於如何使用使用TLS和JMXMP的自定義JMX服務器使用用戶和密碼進行身份驗證

 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); 
     } 
    } 

回答

1

我終於能夠配置更多的用戶和密碼從Oracle文檔與下面的代碼JMXMP連接

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(); 

我實現了一個簡單的CallBackHandler爲密碼驗證

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

你是如何得到這個的? –

+0

您是否必須同樣配置客戶端? – Adam

+0

是的,您需要配置客戶端以使用此類型的身份驗證 –

相關問題