首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用TLS和JMXMP使用自定义JMX服务器使用用户和密码进行身份验证

如何使用TLS和JMXMP使用自定义JMX服务器使用用户和密码进行身份验证
EN

Stack Overflow用户
提问于 2017-07-06 23:20:59
回答 1查看 944关注 0票数 1

按照Oracle文档,我将使用以下代码创建一个带有TLS和JMXMP的自定义JMX服务器。它工作得很好,我可以毫无问题地连接到服务器,但是我想在身份验证中添加"USER“和"PASSWORD”,但是指定"password.properties“和"access.properties”是不起作用的,JMX似乎忽略了这两个选项。有人能解释一下配置用户和密码的正确方法并纠正这个问题吗?谢谢

代码语言:javascript
复制
     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 );
        }
     }
EN

回答 1

Stack Overflow用户

发布于 2017-07-11 02:00:05

我终于能够使用Oracle文档中的以下代码为JMXMP连接配置额外的用户和密码

代码语言:javascript
复制
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

代码语言:javascript
复制
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);
            }
        }
    }
} 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44953031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档