2010-04-16 55 views
6

Giả sử tôi có một lớp singleton trong một thư viện bên ngoài cho ứng dụng của tôi. Nhưng tôi vẫn có thể tạo ra các cá thể của lớp đó bằng cách sử dụng sự phản chiếu. Như thế nàyKhung phản chiếu Java và bảo mật

Class clas = Class.forName(Private.class.getName()); 

    for(Constructor c : clas.getDeclaredConstructors()){ 
     c.setAccessible(true); 
     Private p = (Private) c.newInstance(); 
     System.out.println(p); 
    } 

Làm cách nào để hạn chế điều này? .

Cảm ơn J

+0

Ah những cơn đau của độc thân .. –

+2

Xem thêm: http://stackoverflow.com/questions/2481862/how-to-limit-setaccessible-to-only-legitimate-uses – polygenelubricants

Trả lời

6

Bằng cách sử dụng một SecurityManager và kiểm soát kiểm soát ReflectPermission("suppressAccessChecks") (example).

Trình quản lý bảo mật tác động đến hiệu suất mặc dù nó hiếm khi được sử dụng ở phía máy chủ.

+0

[Làm thế nào lớn là tác động hiệu suất?] (http://stackoverflow.com/questions/14903423/security-manager-rarely-used-on-server) –

0

Dài câu chuyện ngắn: bạn không thể.

Bất kỳ nhà xây dựng nào, công khai cũng như riêng tư, đều có thể được truy cập bằng cách phản ánh và có thể được sử dụng để khởi tạo một đối tượng mới.

Bạn sẽ cần phải sử dụng các phương pháp khác như SecurityManager.

0

Tôi không nghĩ rằng bạn có thể hạn chế điều này. Rõ ràng là một thực tế nguy hiểm/có vấn đề khi sử dụng sự phản chiếu để truy cập các phần riêng tư của người khác (snicker), nhưng đôi khi cần thiết bởi nhiều loại công cụ và ứng dụng khác nhau.

1

Nếu bạn đang nói về độc thân đặc biệt: đó là một lý do tại sao cách tốt nhất để thực hiện chúng là thông qua một enum:

public enum YourSingleton { 
    INSTANCE; 
    // methods go here 
} 

Nếu bạn đang nói về việc sử dụng setAccessible() nói chung: Nếu mã được viết bởi một người nào đó mà bạn không tin tưởng không làm những thủ đoạn bị lừa dối như thế, bạn không nên chạy nó (hoặc chạy nó trong một sandbox). Trong số các nhà phát triển, công chúng/tư nhân nên được xem xét về sự biến đổi về cách mã được dự định sẽ được sử dụng - không phải là một tính năng bảo mật.

0

AFAIK đây là loại lập trình meta và do đó yêu cầu kiểm tra lớp trừu tượng khác nhau. Từ Javadoc tôi cho rằng, bạn nên sử dụng SecurityManager để thực thi hành vi mà bạn muốn: setAccessible(). Nói chung IMHO bạn thực sự nên biết những gì bạn đang làm khi bạn đang metaprogramming và thay đổi truy cập thực sự cần phải có lý do tốt để được thực hiện.

0

Bạn có thể làm như thế này.

private static final Private INSTANCE = new Private(); 
    private Private() { 
     if(INSTANCE !=null) 
      throw new IllegalStateException("Already instantiated"); 
    } 
    public static Private getInstance() { 
      return INSTANCE; 
     } 
+0

Singleton nằm ngoài tầm với của anh ta trong một cái lọ bên thứ ba. Vì vậy, điều này sẽ không giúp gì cả. Kỹ thuật này là bằng cách không an toàn, vì bạn có thể thay đổi nó thông qua sự phản chiếu (như đã đề cập trong câu hỏi). – whiskeysierra

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