1. 程式人生 > 其它 >Nexus Repository Manager 3 遠端命令執行漏洞(CVE-2020-10199)

Nexus Repository Manager 3 遠端命令執行漏洞(CVE-2020-10199)

1、代理模式

為什麼要學習代理模式?因為這就是SpringAOP的底層!【SpringAOP和SpringMVC】

代理模式的分類:

  • 靜態代理

  • 動態代理

1.1、靜態代理

角色分析:

  • 抽象角色:一般會使用介面或者抽象類來解決

  • 真實角色:被代理的角色

  • 代理角色:代理真實角色,代理真實角色後,我們一般會做一些附屬操作

  • 客戶:訪問代理物件的人!

程式碼步驟:

  1. 介面

    //租房
    public interface Rent {
        public void rent();
    }
  2. 真實角色

    //房東
    public class Host implements Rent{
    ​
        @Override
        
    public void rent() { System.out.println("房東要出租房子!"); } }
  3. 代理角色

    public class Proxy implements Rent {
    ​
        private Host host;
    ​
        public Proxy() {
        }
    ​
        public Proxy(Host host) {
            this.host = host;
        }
    ​
        @Override
        public void rent() {
            seeHouse();
            host.rent();
            hetong();
            fare();
        }
    ​
        
    //看房 public void seeHouse(){ System.out.println("中介帶你看房"); } ​ //籤租賃合同 public void hetong(){ System.out.println("籤租賃合同"); } ​ //收中介費 public void fare(){ System.out.println("收中介費"); } }
  4. 客戶端訪問代理角色

    public class Client {
        public static void main(String[] args) {
            
    //房東要租房子 Host host = new Host(); //代理,中介幫房東租房子,但是呢?代理角色一般會有一些附屬操作! Proxy proxy = new Proxy(host); ​ //你不用面對房東,直接找中介租房即可! proxy.rent(); } }

 

代理模式的好處:

  • 可以使真實角色的操作更加純粹!不用去關注一些公共的業務

  • 公共也就交給代理角色!實現了業務的分工

  • 公共業務發生拓展的時候,方便集中管理!

缺點:

  • 一個真實角色就會產生一個代理角色;程式碼量會翻倍-開發效率會變低~

1.2、加深理解

AOP:不通過修改原始碼的方式,將非核心功能程式碼植入來實現對方法的增強。主要使用了代理模式,代理模式的作業是為其他物件提供一種代理,來控制對這個物件的訪問,用於解決在直接訪問物件時遇到的各種問題。代理分為靜態代理和動態代理。

UserService介面

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
}

UserServiceImpl

public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加了一個使用者");
    }
​
    @Override
    public void delete() {
        System.out.println("刪除了一個使用者");
    }
​
    @Override
    public void update() {
        System.out.println("修改了一個使用者");
    }
​
    @Override
    public void query() {
        System.out.println("查詢了一個使用者");
    }
​
    //1.改動原有的業務程式碼,在公司中是大忌!
}

client實現類

public class Client {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
​
        UserServiceProxy proxy = new UserServiceProxy();
        proxy.setUserService(userService);
​
        proxy.delete();
    }
}

UserServiceProxy代理類

public class UserServiceProxy implements UserService{
​
    private UserServiceImpl userService;
​
    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }
​
    @Override
    public void add() {
        log("add");
        userService.add();
    }
​
    @Override
    public void delete() {
        log("delete");
        userService.delete();
    }
​
    @Override
    public void update() {
        log("update");
        userService.update();
    }
​
    @Override
    public void query() {
        log("query");
        userService.query();
    }
​
    //日誌方法
    public void log(String msg){
        System.out.println("[Debug]使用了" + msg + "方法");
    }
}

1.3、動態代理

  • 動態代理和靜態代理角色一樣

  • 動態代理的代理類時動態生成的,不是我們直接寫好的!

  • 動態代理分為兩大類:基於介面的動態代理,基於類的動態代理

    • 基於介面---JDK動態代理【我們在這裡使用】

    • 基於類:cglib

    • java位元組碼實現:javassist

需要了解兩個類:Proxy:代理,InvocationHandler:呼叫處理程式

萬能模板:ProxyInvocationHandler類

//我們會用這個類自動生成代理類!
public class ProxyInvocationHandler implements InvocationHandler {
​
    //被代理的介面
    private Object target;
​
    public void setTarget(Object target) {
        this.target = target;
    }
​
    //生成得到代理類
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }
​
    //處理程式碼例項,並返回結果:
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());
        Object result = method.invoke(target, args);
        return result;
    }
​
    public void log(String msg){
        System.out.println("執行了"+msg+"方法");
    }
​
}

Client實現類:

public class Client {
    public static void main(String[] args) {
        //真實角色
        UserServiceImpl userService = new UserServiceImpl();
        //代理角色,不存在
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
​
        pih.setTarget(userService);//設定要代理的物件
        //動態生成代理類
        UserService proxy = (UserService) pih.getProxy();
​
        proxy.add();
​
    }
}

動態代理的好處:

  • 可以使真實角色的操作更加純粹!不用去關注一些公共的業務

  • 公共也就交給代理角色!實現了業務的分工

  • 公共業務發生拓展的時候,方便集中管理!

  • 一個動態代理類代理的是一個介面,一般就是對應的一類業務

  • 一個動態代理類可以代理多個類,只有是實現了同一個介面即可