Java 安全保护系统资源免受不可信代码的未授权访问。代码可以通过签名者和代码库 url(jar 或类文件)来识别,它可以是本地的或从网络下载的。CGLIB 生成的类在配置和 JVM 启动时不存在(在运行时生成),但所有生成的类都具有与 cglib 本身相同的保护域(签名者和代码库),并且可以在 WS 中使用或由带有安全管理器的 RMI 应用程序使用。要为生成的类授予权限,请为 cglib 二进制文件授予权限。默认安全配置在 java.policy 文件中。这是示例策略文件,它授予 cglib 和生成代码的所有权限。
grant codeBase "file:${user.dir}/jars/cglib.jar"{ permission java.security.AllPermission; };
Java 对象可以序列化为二进制流,它也用于实现 RMI。序列化需要在反序列化对象数据之前加载类。客户端或服务器上可能没有为未编组对象生成的类,但序列化允许替换流中的对象(writeReplace/readResolve 约定)。将 “writeReplace” 方法添加到代理类中,在接口中声明此方法,并具有 Java 序列化指定的确切签名。在拦截器中实现 writeReplace。代理对象可以用句柄代替,对象流在反序列化句柄之前调用 “readResolve”。在反序列化句柄并返回代理实例之前,在 “readResolve” 方法中生成或查找代理类。
这是一个仅捕获字节数组的示例:
Enhancer e = new Enhancer(); e.setSuperclass(...); // etc. e.setStrategy(new DefaultGeneratorStrategy() { protected byte[] transform(byte[] b) { // do something with bytes here } }); Object obj = e.create();
您还可以轻松挂钩 ClassTransformer 以影响生成的类,而无需重新解析字节数组,例如:
e.setStrategy(new DefaultGeneratorStrategy() { protected ClassGenerator transform(ClassGenerator cg) { return new TransformingGenerator(cg, new AddPropertyTransformer(new String[]{ "foo" }, new Class[]{ Integer.TYPE })); } });
设置 “cglib.debugLocation” 系统属性以将生成的类和伪 ASM 代码写入文件系统。NamingPolicy 可用于生成更有意义的名称。
常见的错误是在 MethodInterceptor 实现中引起递归:
Object intercept(Object proxy, Method method, MethodProxy fastMethod, Object args[]) throws Throwable { //ERROR System.out.println(proxy.toString()); //ERROR return fastMethod.invoke(proxy,args); }
必须使用 invokeSuper 方法来调用超类方法。如果 super 方法是抽象的,它将抛出 AbstractMethodError。
使用 CallbackFilter 过滤未使用的方法并尽可能使用轻量级回调版本。如果您也使用每个方法拦截器,它可以帮助避免对方法对象进行哈希查找。
原文地址:https://github.com/cglib/cglib/wiki/How-To#cglib-and-java-security