Ограничение доступа к файлам в Java

Проблема:
В моем Java-приложении (не апплете) я хочу ограничить определенные файловые операции всеми классами, кроме списка/группы/пакета классов, которые не должны ограничиваться.

В частности, я хотел бы ограничить...

  • Файл читает
  • Файл пишет
  • Создание файла
  • Удаление файла

... так что они могут быть выполнены только в текущем рабочем каталоге для всех классов, кроме неограниченных.

Попытка SecurityManager:
я попытался реализовать подкласс класса SecurityManager, который реализует это поведение, однако кажется, что при выполнении проверок предоставленная информация file не дайте больше, чем просто имя файла (если я что-то упустил?).

Кроме того, я не совсем понимаю, как в этом случае я мог бы узнать класс, из которого выполняется вызов, чтобы я мог определить, разрешать ли операцию или генерировать исключение. Есть ли способ получить всю информацию, необходимую для работы этого подхода?

Попытка на основе политик
Мне также известно, что политики Java предназначены для ограничения действий классов, включая такие вещи, как операции с файлами. Однако я изо всех сил пытался найти хороший ресурс, чтобы узнать, как решить свои проблемы с помощью файла .policy.

Обобщение вопроса:

1) Существуют ли альтернативные подходы, которые могут быть предпочтительнее упомянутых мной?

2) Возможно ли это с помощью SecurityManager? Я упускаю из виду, как я должен на самом деле реализовать такой подход?

3) Возможно ли это с помощью файла политики? Есть ли какие-нибудь хорошие ресурсы, которые я пропустил на этом фронте?

На самом деле я не возражаю против большого количества тяжелой работы, которую мне нужно вложить для достижения этой цели — я просто не знаю, как правильно подойти к этому. Мне также очень не хватает хороших ресурсов, чтобы научить меня достаточному количеству двух возможных подходов, которые я упомянул, чтобы позволить мне реализовать их самостоятельно. Прежде всего, я не боюсь много читать там, где это необходимо!

Спасибо за любую помощь, которую вы можете оказать, заранее.


person obfuscation    schedule 02.04.2011    source источник


Ответы (1)


Вот как это можно сделать с помощью файла политики.

Создайте файл Java, который может действовать с привилегиями:

package egPriv;

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

public class PrivCat {
    /** Cat a file with no privileges */
    public void cat(String file) throws IOException {
        cat(new FileReader(file));
    }

    private void cat(Reader r) throws IOException {
        int c;
        while( (c = r.read()) != -1 ) {
            System.out.print((char) c);
        }
        r.close();
    }

    /** Cat a file WITH privileges */
    public void catPriv(final String file) throws IOException {
        Reader r;
        try {
            r = AccessController.doPrivileged(new PrivilegedExceptionAction<Reader>() {
                public Reader run() throws IOException {
                    return new FileReader(file);
                }
            });
        } catch (PrivilegedActionException e) {
            throw (IOException) e.getCause();
        }
        cat(r);
    }
}

Создайте обычный файл для демонстрации

package eg;

import egPriv.PrivCat;

import java.io.IOException;

public class Cat extends PrivCat {
    public static void main(String[] args) throws IOException {
        Cat eg2 = new Cat();
        System.out.println("Processing with privilege:");
        eg2.catPriv(args[0]);

        System.out.println("Processing normally");
        eg2.cat(args[0]);
    }
}

Создайте файл sample.policy:

/* anyone can read write and execute within current working dir */
grant {
  permission java.io.FilePermission "${user.dir}", "read,write,execute";
};

grant {
  permission java.io.FilePermission "${user.dir}/*", "read,write,execute,delete";
};


/* Only code from this jar can work outside of CWD */
grant codebase "file:egPriv.jar" {
  permission java.io.FilePermission "<<ALL FILES>>", "read,write,execute,delete";
};

Скомпилируйте, а затем протестируйте:

jar cvf egPriv.jar egPriv
jar cvf eg.jar eg


echo 'Restricted' > ..\file.txt
java -cp eg.jar;egPriv.jar -Djava.security.manager -Djava.security.policy=sample.policy  eg.Cat ..\file.txt

echo 'Open' > file.txt
java -cp eg.jar;egPriv.jar -Djava.security.manager -Djava.security.policy=sample.policy  eg.Cat file.txt
person Simon G.    schedule 03.04.2011
comment
если вы добавите -Djava.security.debug=All в командную строку, вывод может оказаться весьма полезным для выяснения, почему ваш файл политики не работает. - person Simon G.; 03.04.2011
comment
Во-первых, большое спасибо, я сейчас тестирую эту реализацию. Во-вторых, еще один быстрый вопрос: может ли это сосуществовать с SecurityManager, который реализует некоторые другие потребности в защите, которые у меня есть? - person obfuscation; 03.04.2011
comment
Сначала консультируются с SecurityManager, а с политиками — только в том случае, если это делает менеджер безопасности. SecurityManager по умолчанию делегирует полномочия в политиках для всего. Если вы подклассифицируете SecurityManager, чтобы сделать что-то еще для какой-то проверки, то разрешения не смогут предоставить требуемую привилегию для этой проверки. - person Simon G.; 03.04.2011
comment
Например, если вы хотите запретить коду изменять текущий рабочий каталог, установив системное свойство ${user.dir} и, следовательно, обходя привилегии, вы можете переопределить метод SecurityManager.checkPropertyAccess, чтобы он всегда выдавал исключение SecurityException, тогда никакие привилегии и свойства не будут разрешить коду устанавливать свойство. - person Simon G.; 03.04.2011