JMX安全漏洞修复 服务端增加用户名和密码验证机制

方式1 启动脚本中增加参数

-Djmx.authenticate=true -Djmx.password=$base/conf/jmxremote.password -Djmx.access=$base/conf/jmxremote.access

方式2 启动程序中设置环境变量

前提是继承 extends ConnectorServerFactoryBean类
配置文件增加属性:
	# 是否启用JMX
	jmx.authenticate = true
	# jmxremote.access文件路径
	jmxremote.access.path = ${user.dir}/../conf/jmxremote.access
	# jmxremote.password文件路径
	jmxremote.password.path = ${user.dir}/../conf/jmxremote.password

private void setJMXParameter() {
        if ("true".equalsIgnoreCase(jmxAuthenticate)) {
            Properties prop = new Properties();
            prop.put("jmx.remote.x.password.file", jmxPassword);
            prop.put("jmx.remote.x.access.file", jmxUsername);
            prop.put("jmx.remote.x.mlet.allow.getMBeansFromURL", false);
            setEnvironment(prop);
        }
    }

附:
jmxremote.access 文件下载
jmxremote.password 文件下载

demo:

package com.tongtech.remote.impl;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.*;
import javax.management.remote.rmi.RMIConnectorServer;
import javax.security.auth.Subject;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.RMISocketFactory;
import java.util.*;

/**
 * @Auther: zhaoshuangjian  2023-04-25 10:07 PM
 */
public class UserJmxServer {

    public static void main(String[] args){

//        MBeanServer mBeanServer;
//        User bean=new User();

        try {

            MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); //向MBeanServer注册mbean
            ObjectName objectName = new ObjectName("user:name=User");
            mBeanServer.registerMBean(new User(), objectName);
            JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/user");
            System.out.println("JMXServiceURL: " + jmxServiceURL.toString());
            Map<String ,Object> jmxEnv=new HashMap<String,Object>();
            RMISocketFactory rmiFactory = RMISocketFactory.getDefaultSocketFactory();
            Registry registry = LocateRegistry.createRegistry(1099,null, rmiFactory); //构造 JMXServiceURL
            jmxEnv.put("jmx.remote.credentials", new String[]{"admin","admin123"});
            jmxEnv.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, rmiFactory);
            JMXAuthenticator auth = createJMXAuthenticator();
            jmxEnv.put(JMXConnectorServer.AUTHENTICATOR, auth);
            jmxEnv.put("jmx.remote.x.mlet.allow.getMBeansFromURL","false");
            JMXConnectorServer jmxConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, jmxEnv, mBeanServer);
            jmxConnectorServer.start();
            System.out.println("JMXConnectorServer is running");
//            int rmiPort = 6090;
//            Registry registry = LocateRegistry.createRegistry(rmiPort);
//            mBeanServer = MBeanServerFactory.createMBeanServer("user");
//
//            ObjectName objectName = new ObjectName("user:name=User");
//            mBeanServer.registerMBean(bean, objectName);
//
//            JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:6090/mbean");
//            System.out.println("JMXServiceURL: " + url.toString());
//            Map<String ,Object> jmxEnv=new HashMap<String,Object>();
//            jmxEnv.put("jmx.remote.credentials", new String[]{"admin","admin123"});
//            JMXAuthenticator auth = createJMXAuthenticator();
//            jmxEnv.put(JMXConnectorServer.AUTHENTICATOR, auth);
            jmxEnv.put("jmx.remote.x.mlet.allow.getMBeansFromURL","false");
//            JMXConnectorServer jmxConnServer = JMXConnectorServerFactory.newJMXConnectorServer(url, jmxEnv, mBeanServer);
//            jmxConnServer.start();

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





    /**
     *  认证
     * @return
     */
    private static JMXAuthenticator createJMXAuthenticator(){
        return new JMXAuthenticator()
        {
            public Subject authenticate(Object credentials) {
                String[] sCredentials = (String[]) credentials;
                if (null == sCredentials || sCredentials.length != 2) {
                    throw new SecurityException("Authentication failed!");
                }
                String userName = sCredentials[0];
                String pValue = sCredentials[1];
                if ("admin".equals(userName) && "admin123".equals(pValue)) {
                    Set<JMXPrincipal> principals = new HashSet<JMXPrincipal>();
                    principals.add(new JMXPrincipal(userName));
                    System.out.println("认证成功");
                    return new Subject(true, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
                }
                throw new SecurityException("Authentication failed!");
            }
        };
    }
}






package com.tongtech.remote.impl;

/**
 * @Auther: zhaoshuangjian  2023-04-25 10:05 PM
 */
public interface JMXUserMBean {
    Long getUserId();
    String getUserName();
    String getPassWord();
    void setUserId(Long userId);
    void setUserName(String userName);
}


package com.tongtech.remote.impl;

/**
 * @Auther: zhaoshuangjian  2023-04-25 10:06 PM
 */
public class User implements JMXUserMBean {
    Long userId = 12345678L;
    String userName = "jvm-user";
    @Override
    public Long getUserId() {
        return userId;
    }

    @Override
    public String getUserName() {
        return userName;
    }

    @Override
    public void setUserId(Long userId) {
        this.userId = userId;
    }

    @Override
    public void setUserName(String userName) {
        this.userName = userName;
    }
}


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhaoshuangjian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值