2011-09-27 17 views
22

Làm thế nào để hạn chế các nhà phát triển sử dụng sự phản chiếu để truy cập các phương thức riêng và các nhà xây dựng trong Java?Làm thế nào để hạn chế các nhà phát triển sử dụng sự phản chiếu để truy cập các phương thức riêng và các nhà xây dựng trong Java?

Sử dụng mã Java thông thường, chúng tôi không thể truy cập các nhà thầu tư nhân hoặc các phương thức riêng tư bên ngoài lớp học. Nhưng bằng cách sử dụng sự phản chiếu, chúng ta có thể truy cập bất kỳ phương thức riêng và các hàm tạo nào trong một lớp Java.

Vậy làm cách nào chúng tôi có thể cung cấp bảo mật cho mã Java của mình?

+0

Đây sẽ là một lựa chọn tốt đẹp để có cho hộp, bình ký kết. "Trong mọi trường hợp, cho phép phản chiếu đối với các lớp trong tệp jar này". Nhưng tôi nghĩ, không có tính năng như vậy. – Thilo

Trả lời

2

Bạn (với tư cách là nhà phát triển mã được đề cập) không thể làm điều đó.

Người dùng cuối, người điều hành ứng dụng, có thể cài đặt SecurityManager để tránh phản ánh.

+0

Tất nhiên là có thể. Anh ta cài đặt trình quản lý bảo mật trong khi khởi động ứng dụng của mình. –

+0

Đó không phải là một tùy chọn trừ khi anh ta là nhà phát triển ứng dụng. Tôi đã suy nghĩ nhiều hơn về trường hợp anh ta "muốn hạn chế các nhà phát triển [có lẽ là ứng dụng] để sử dụng sự phản chiếu" chống lại các phương pháp mà anh ta muốn giữ riêng tư. – Thilo

+0

Điều gì ngăn cản anh ta để có một initializer tĩnh trong các lớp học của mình mà cài đặt một người quản lý bảo mật? Và ofc throiws là một ngoại lệ ngăn cản việc mã hóa lớp, nếu anh ta không thể cài đặt nó? –

6

Thêm phương thức checkPermission() vào tất cả phương thức/phương thức riêng của bạn. checkPermission sử dụng sun.reflect.Reflection.getCallerClass(int n) bằng cách khẳng định callerClass=selfClass.

getCallerClass trả về lớp của phương thức realFramesToSkip khung lên ngăn xếp (không dựa trên cơ sở), bỏ qua các khung được liên kết với java.lang.reflect.Method.invoke() và triển khai. Khung đầu tiên được liên kết với phương thức này, do đó, getCallerClass(0) trả về đối tượng Lớp cho sun.reflect.Reflection.

public class PrivateConstructorClass { 

    private PrivateConstructorClass() { 
     checkPerMission(); 
       //you own code go below 
    } 

    void checkPerMission() { 
     Class self = sun.reflect.Reflection.getCallerClass(1); 
     Class caller = sun.reflect.Reflection.getCallerClass(3); 
     if (self != caller) { 
      throw new java.lang.IllegalAccessError(); 
     } 
    } 
} 

Bạn có thể thử để kiểm tra phản ánh, nó sẽ thất bại:

public class TestPrivateMain { 

    Object newInstance() throws Exception { 

     final Class<?> c = Class.forName("package.TestPrivate"); 

     final Constructor<?> constructor = c.getDeclaredConstructor(); 
     constructor.setAccessible(true); 
     return constructor.newInstance(); 

    } 

    public static void main(String[] args) throws Exception { 
     Object t = new TestPrivateMain().newInstance(); 
    } 
} 
+2

-1: để gọi không ổn định "API" như sun.reflect.Reflection ... –

+2

Hmm ... Nhưng đó là một thử tốt thực sự trong quan điểm của tôi .. Không ổn định API không nên có mặt ở nơi đầu tiên –

Các vấn đề liên quan