Каковы потери производительности, если таковые имеются, использования SecurityManager - PullRequest
9 голосов
/ 22 ноября 2011

Есть ли снижение производительности при использовании SecurityManager?

Мне нужно следующее:

public class ExitHelper {

    public ExitHelper() {

        System.setSecurityManager(new ExitMonitorSecurityManager());

    }

    private static class ExitMonitorSecurityManager extends SecurityManager {

        @Override
        public void checkPermission(Permission perm) {}

        @Override
        public void checkPermission(Permission perm, Object context) {}

        @Override
        public void checkExit( final int status ) {
            // this is the part I need and I don't care much about the performance issue of this method
        }
}

Это окажет огромное влияние на мою программу?

программа действительно открывает много файлов, например.И если я включу SecurityManager и добавлю туда логирование, то смогу много раз вызывать эти методы.Действительно много.Настолько, что нормальное ведение журнала теряется при ведении журнала этими двумя методами.Таким образом, кажется, что установка SecurityManager означает, что совершается множество вызовов.Будет ли это медленнее, чем по умолчанию SecurityManager?(есть ли по умолчанию?)

Как это работает?Какая часть программы будет проверяться на наличие разрешений и как часто?Я обеспокоен двумя checkPermission (...) методами.

Ответы [ 3 ]

7 голосов
/ 22 ноября 2011

Производительность снижается, но, скорее всего, она небольшая, потому что:

  • Применяется только при попытке выполнить какую-либо форму действий, требующую проверки прав доступа.
  • БольшинствоОперации, требующие проверки разрешений, являются дорогостоящими операциями (ввод-вывод, доступ к сети и т. д.), поэтому вполне вероятно, что накладные расходы на проверки безопасности составят довольно низкий процент от общего времени выполнения.
  • Сама проверка может бытьсделано очень дешево

В частности, обратите внимание, что вызывающий код для проверок безопасности обычно очень легок в коде библиотеки Java, то есть что-то вроде этого:

 SecurityManager security = System.getSecurityManager();
 if (security != null) {
     security.checkXXX(argument,  . . . );
 }

Если ваша безопасностьСам код менеджера одинаково легок, тогда затраты времени выполнения проверки безопасности должны быть незначительными.Однако я бы избегал размещения любого кода регистрации в самом SecurityManager - это было бы дорого и, вероятно, относится к более высокому уровню в коде вашего приложения.

Если вы хотите абсолютно минимизировать накладные расходыменеджер безопасности для разрешений, которые вас не волнуют, тогда вы должны переопределить конкретные методы checkXXX, которые вам не нужны, с помощью чего-то вроде:

@Override 
public void checkRead(String file) {
  // empty method as we are happy to allow all file reads
}

В конечном итоге вам придется сравнивать для вашего конкретногоситуация, но ответ «интуитивное чувство» будет то, что вы не должны беспокоиться об этом.

2 голосов
/ 31 августа 2017

У меня есть некоторые эмпирические доказательства, чтобы внести свой вклад после реализации вопроса администратора безопасности:

java SecurityManager, идентичный NO менеджер безопасности, за исключением настройки одной проверки для System.exit

Влияние производительности на этот анонимный внутренний класс было ОГРОМНЫМ:

        System.setSecurityManager(new SecurityManager() {
            @Override
            public void checkPermission(Permission perm) {
                return; // no security manager behaviour
            }

            @Override
            public void checkPermission(Permission perm, Object context) {
                return; // no security manager behaviour
            }

            @Override
            public void checkExit(int status) {
                Thread.dumpStack();
                super.checkExit(status);
            }
        });

Мой опыт после запуска моего приложения в Eclipse заключался в том, что оно было заметно медленнее, и я подтвердил то же самое на компьютере коллеги.

Так что я чувствую, что «незначительное» может быть преуменьшением (и мой вариант использования даже не выполняет никаких проверок!). Считайте это анекдотом, что это не так.

В качестве еще одного примечания: я создал конечный класс с проверками бездействия для ВСЕХ методов, чтобы избежать создания экземпляров объектов разрешений и тому подобного (в конце попросите компилятор jit подключить его) При таком подходе влияние на производительность было действительно минимальным. Таким образом, для людей, которые просто хотят добавить пару конкретных проверок (а не полагаться на политики Java), это фактически оказывает незначительное влияние:

public final class SystemExitTraceSecurityManager extends SecurityManager {

    @Override
    public final void checkAccept(String host, int port) {
    }

    @Override
    public final void checkAccess(Thread t) {
    }

    @Override
    public final void checkAccess(ThreadGroup g) {
    }

    @Override
    public final void checkAwtEventQueueAccess() {
    }

    @Override
    public final void checkConnect(String host, int port) {
    }

    @Override
    public final void checkConnect(String host, int port, Object context) {
    }

    @Override
    public final void checkCreateClassLoader() {
    }

    public final void checkDelete(String file) {
    };

    @Override
    public final void checkExec(String cmd) {
    }

    public final void checkExit(int status) {
        Thread.dumpStack();
    };

    @Override
    public final void checkLink(String lib) {
    }

    @Override
    public final void checkListen(int port) {
    }

    @Override
    public final void checkMemberAccess(Class<?> clazz, int which) {
    }

    @Override
    public final void checkMulticast(InetAddress maddr) {
    }

    @Override
    public final void checkMulticast(InetAddress maddr, byte ttl) {
    }

    @Override
    public final void checkPackageAccess(String pkg) {
    }

    @Override
    public final void checkPackageDefinition(String pkg) {
    }

    @Override
    public final void checkPermission(Permission perm) {
    }

    @Override
    public final void checkPermission(Permission perm, Object context) {
    }

    @Override
    public final void checkPrintJobAccess() {
    }

    @Override
    public final void checkPropertiesAccess() {
    }

    public final void checkPropertyAccess(String key) {
    };

    @Override
    public final void checkRead(FileDescriptor fd) {
    }

    @Override
    public final void checkRead(String file) {
    }

    @Override
    public final void checkRead(String file, Object context) {
    }

    @Override
    public final void checkSecurityAccess(String target) {
    }

    @Override
    public final void checkSetFactory() {
    }

    @Override
    public final void checkSystemClipboardAccess() {
    }

    @Override
    public final boolean checkTopLevelWindow(Object window) {
        return true;
    }

    @Override
    public final void checkWrite(FileDescriptor fd) {
    }

    @Override
    public final void checkWrite(String file) {
    }
}
2 голосов
/ 22 ноября 2011

да, есть потеря производительности.если вы обеспокоены этим, единственным выходом для вас является измерить его и посмотреть, слишком ли велик штраф.

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

System.setSecurityManager(new ExitMonitorSecurityManager());
try {
  // ... do protected op here ...
} finally {
  System.setSecurityManager(null);
}

ОБНОВЛЕНИЕ:

, чтобы разъяснить тем, кто может прийти к этому ответу позже, этот ответ не предназначен для работы с потенциально вредоносным кодом.В этой ситуации соответствующим образом сконфигурированный SecurityManager должен быть постоянно .В этом ответе предполагается, что OP пытается справиться с плохо написанной сторонней библиотекой, которая в какой-то четко определенный момент времени вызывает неудачный вызов System.exit ().

...