安全开发Java动态代理

  关于安全开发的一些思考html

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

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

  静态代理面试

  jdk动态代理安全

  CGLIB代理ide

  Spring AOP函数

  

 

  为何使用动态代理this

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

  静态代理htm

  定义接口:

  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

相关文章
相关标签/搜索