zoukankan      html  css  js  c++  java
  • 安全开发Java动态代理

      关于安全开发的一些思考

      之前面试某宝的时候,某人问过我,如果解决开发不懂安全的问题,就比如说SSRF,XEE这样的漏洞,如果一旦发生,应该如果立刻去响应,并帮助开发人员修复漏洞,难道写一个jar包?然后丢给数以百计的业务去调用?还是你去手把手的去教给开发,应该如何修改代码!!

      其实在java动态代理中,就已经解决了这种问题,本人将从以下几个方面,帮助大家理解动态代理的知识。对于懂java的“安全牛”来说这是一件很简单的事情,本文目的主要是记录下解决问题的过程。

      静态代理

      jdk动态代理

      CGLIB代理

      Spring AOP

      

      为什么使用动态代理

      作为在乙方工作的“安全工程狮”有时候想一下还是幸福的,最近通过跟甲方的某狮子交流,发现业务量很大的情况下,一旦发生了安全问题,解决起来真是个麻烦的事情,需要收集资产,要出方案,最难的是教会开发修补漏洞,仔细思考了这个问题,遂想到了java动态代理,周末的时候研究了一下,现在分享给大家。设想一下,如果你挨个去教给开发应该怎么去修复漏洞,那么24小时之内完成应急是根本不可能完成的。比较高效的方法是,安全的逻辑都由安全部门实现,我们只需要留给开发一个接口供他们去使用就ok。那怎么样才可能通过,不修改源代码的情况下,增加业务的安全性,就是通过今天说的java动态代理。

      静态代理

      定义接口:

      public interface Hello1 {

      public void say(String name);

      }

      复制代码

      实现类:

      public class HelloImpl implements Hello1{

      @Override

      public void say(String name) {

      // TODO Auto-generated method stub

      System.out.println("Hello"+name);

      }

      }

      复制代码

      hello1代理类: public class HelloProxy implements Hello1{ private Hello1 hello;

      public HelloProxy(){

      hello=new HelloImpl();

      }

      @Override

      public void say(String name){

      before();

      hello.say(name);

      after();

      }

      private void after() {

      // TODO Auto-generated method stub

      System.out.println("after");

      }

      private void before() {

      // TODO Auto-generated method stub

      System.out.println("before");

      }

      }

      复制代码

      主函数:

      public static void main(String[] args){

      Hello1 helloProxy=new HelloProxy();

      helloProxy.say("Jack");

      }

      复制代码

      由上面的过程可以看得出来,我们通过hello1的代理类,增加了say()函数,通过代理,实现了before和after函数。这就是我要说的代理,只不过这事静态代理,通用性差,修改起来麻烦。下面说动态代理。

      jdk动态代理

      public class DynamicProxy2 implements InvocationHandler {

      public Object target;

      @SuppressWarnings("unchecked")

      public <T> T getProxy(){

      return (T)Proxy.newProxyInstance(target.getClass().getClassLoader(),

      target.getClass().getInterfaces(), this);

      }

      public DynamicProxy2(Object target) {

      // TODO Auto-generated constructor stub

      this.target=target;

      }

      @Override

      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

      // TODO Auto-generated method stub

      before();

      Object result=method.invoke(target, args);

      after();;

      return result;

      }

      private void after() {

      // TODO Auto-generated method stub

      System.out.println("after");

      }

      private void before() {

      // TODO Auto-generated method stub

      System.out.println("before");

      }

      复制代码

      主函数:

      public static void main(String[] args) {

      // TODO Auto-generated method stub

      DynamicProxy2 dynamicProxy2 = new DynamicProxy2(new HelloImpl());

      Hello1 helloproxy= dynamicProxy2.getProxy();

      helloproxy.say("hi java");

      }

      复制代码

      这里可以看到通过jdk动态代理,首先实现InvocationHandler接口,然后实现了invoke方法。从主函数中可以看到,这里我们并不关心你的类是什么,你的接口是什么,只要你把实现接口的类传递进来,就可以了,这个方案看起来是很不错的。好像可以解决一开始的需求,但是jdk动态代理只能代理接口,而不能代理没有接口的类,这种情况该怎么解决?

      CGLIB动态代理

      public class CGLibProxy implements MethodInterceptor {

      @SuppressWarnings("unchecked")

      public<T> T getProxy(Class<T> cls){

      return (T) Enhancer.create(cls, this);

      }

      @Override

      public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

      // TODO Auto-generated method stub

      before();

      Object result=proxy.invokeSuper(obj, args);

      after();

      return result;

      }

      private void after() {

      // TODO Auto-generated method stub

      System.out.println("after");

      }

      private void before() {

      // TODO Auto-generated method stub

      System.out.println("before");

      }}

      复制代码

      主函数:

      public static void main(String[] args) {

      // TODO Auto-generated method stub

      CGLibProxy cglibproxy=new CGLibProxy();

      Hello1 helloproxy=cglibproxy.getProxy(HelloImpl.class);

      helloproxy.say("asd");

      }

      复制代码

      这里需要引入开篇时候的那个jar包。CGLIB可以代理没有接口的类,这就弥补了jdk动态代理的不足。通过jdk,cglib动态代理,就可以解决以上遇到的问题。

      来自:http://www.freebuf.com/articles/web/118334.html

  • 相关阅读:
    浏览器低延时播放监控摄像头视频(EasyNVR播放FLV视频流)
    RTSP/Onvif摄像机在做H5无插件直播中遇到对接海康摄像机发送OPTIONS心跳的问题
    EasyDarwin系列互联网视频直播录像方案的选择
    EasyNVR配置需求
    EasyNVR硬件云终端与EasyNVR综合对比
    EasyNVR使用过程中问题的自我排查设备不在线问题自我排查检测
    EasyNVR在Linux系统下将录像文件与EasyNVR运行分离
    EasyNVR硬件云终端使用说明(问题的自我排查与解决)
    EasyNVR内网接入网关+EasyNVS云端管理平台,组件起一套轻量级类似于萤石云的解决方案
    EasyNVR支持的设备接入类型以及关于国标设备是否支持接入EasyNVR
  • 原文地址:https://www.cnblogs.com/anjijiji/p/7154173.html
Copyright © 2011-2022 走看看