Службы авторизации, сохраняющие аутентификацию с течением времени

#macos #authorization

#macos #авторизация

Вопрос:

Я хотел бы знать, возможно ли сохранять приобретенную аутентификацию с течением времени.
Вот мой код:

 - (IBAction)toggleAuthentification:(id)sender {
    if (AuthorizationCopyRights(authRef, amp;authRights, kAuthorizationEmptyEnvironment, authFlags ^ kAuthorizationFlagInteractionAllowed, NULL) == errAuthorizationSuccess) {
        AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
        authRef = NULL;
        AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, amp;authRef);
        [sender setState:NSOffState];
    } else if (AuthorizationCopyRights(authRef, amp;authRights, kAuthorizationEmptyEnvironment, authFlags, NULL) == errAuthorizationSuccess) {
        AuthorizationMakeExternalForm(authRef, amp;extAuthRef);
        [sender setState:NSOnState];

        NSDictionary *authRightInfo;
        if (AuthorizationRightGet(authRights.items[0].name, (CFDictionaryRef *)amp;authRightInfo) == errAuthorizationSuccess) {
            //[authRightInfo valueForKey:@"timeout"] == 300
            keepAuthTimer = [NSTimer scheduledTimerWithTimeInterval:([[authRightInfo valueForKey:@"timeout"] unsignedShortValue] - 10) target:self selector:@selector(keepAuthentification:) userInfo:nil repeats:YES];
        }
    } else {
        [sender setState:NSOffState];
    }
}

- (void)keepAuthentification:(NSTimer *)aTimer {
    NSLog(@"%d", AuthorizationCopyRights(authRef, amp;authRights, kAuthorizationEmptyEnvironment, authFlags ^ kAuthorizationFlagInteractionAllowed, NULL));
    NSLog(@"keepAuth", aTimer);
}
  

Шаг 1: нажмите на кнопку, которая вызывает toggleAuthentification: и авторизируется успешно.
Шаг 2: Через 290 секунд я получаю 0 и keepAuth с консоли, таким образом, мой NSTimer работает.
Шаг 3: подождите еще несколько секунд (более 10) и снова нажмите на мою кнопку. Панель авторизации снова появится!!!

Почему мой вызов AuthorizationCopyRights into keepAuthentification: не сбрасывает тайм-аут в 300 секунд (для этого права авторизации)?

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

Ответ №1:

Где задокументировано, что AuthorizationCopyRights предполагается сброс таймера? AuthorizationCopyRights запросит запрошенные права у подсистемы безопасности, и подсистема безопасности либо сразу предоставит права, либо предложит пользователю авторизоваться. Время ожидания, через сколько секунд система должна повторно запросить авторизацию пользователя, настраивается в /etc/authorization , и оно также может быть установлено равным 0, что означает, что системе всегда приходится повторно запрашивать пользователя.

Если вы хотите использовать права авторизации для запуска инструмента с правами root (вспомогательный инструмент) несколько раз в будущем, просто выполните следующие действия:

  • Когда вам нужно запустить приложение с правами root в первый раз, попросите пользователя авторизоваться.

  • Когда авторизация завершится успешно, не запускайте вспомогательный инструмент напрямую, а запустите вспомогательный инструмент с правами root.

  • Вспомогательный инструмент продолжает работать в фоновом режиме, пока ваше приложение не сообщит ему о завершении работы, что произойдет, когда само ваше приложение завершит работу или когда пользователь отменит авторизацию.

  • Вспомогательный инструмент взаимодействует с вашим приложением с помощью какого-либо метода IPC. Например.:

    1. Он считывает команды из stdin — при запуске задачи вы можете получить доступ к ее каналу stdin (см. Параметр communicationsPipe для AuthorizationExecuteWithPrivileges).

    2. Если вспомогательный инструмент написан на Obj-C, вы можете использовать распределенные объекты.

    3. Если это написано не на Obj-C и вы по какой-либо причине не хотите использовать файловый канал, вы можете предпочесть использовать сокеты UNIX. Сокеты UNIX работают как сетевые сокеты, но без использования сетевого протокола или сетевых адресов. Любой процесс открывает серверный UNIX-сокет, а другой процесс создает клиентский UNIX-сокет и подключает его к серверному сокету. Теперь оба процесса могут обмениваться данными через этот сокет (в обоих направлениях, поскольку сокеты всегда двунаправленные).

    4. Если вам необходимо отправить много данных в свой вспомогательный инструмент, все описанные выше методы могут быть довольно медленными, поскольку они включают копирование данных или даже преобразование, копирование и повторное преобразование. В этом случае используйте общую память POSIX для передачи данных (это самый быстрый способ передачи данных между процессами, поскольку данные вообще не передаются, они просто доступны нескольким процессам одновременно) и используйте только любой из описанных выше методов, чтобы сообщить другому процессу, что содержимое памяти было обновлено.

  • Теперь отправьте вспомогательному инструменту команду, которая заставит его запустить вспомогательный инструмент (с соответствующими параметрами). Поскольку вспомогательный инструмент запускается от имени root, вспомогательный инструмент также будет запускаться от имени root.

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

  • В тех случаях, когда вы хотите запустить вспомогательный инструмент без прав root, просто вызовите его напрямую, не используя вспомогательный инструмент helper.

Конечно, описанный выше метод слишком сложен, но, вероятно, его проще всего применить к вашему текущему коду. Лично я бы вообще не стал использовать вспомогательный инструмент, а вместо этого заставил бы сам вспомогательный инструмент постоянно работать в фоновом режиме. Затем вспомогательный инструмент либо напрямую выполнит запрошенные действия, либо, если это невозможно по какой-либо причине, разветвляется и затем выполняет действия (это не сработает, если вы используете CoreFoundation, Foundation или некоторые другие платформы Apple), либо разветвляется, а затем повторно выполняется с параметром, который указывает ему просто выполнить определенное действие, а затем выйти. Преимущество в том, что будет только один вспомогательный инструмент.

Комментарии:

1. Я хотел бы иметь приложение, в котором вам нужно входить в систему только один раз за выполнение приложения или до тех пор, пока вы вручную не запросите выход, нажав кнопку.

2. Но для чего вы используете авторизацию? Используете ли вы какие-либо инструменты с правами root, например?

3. Да, точно, у меня есть основное приложение, в котором вы можете выполнять аутентификацию ( AuthorizationRights содержать только kAuthorizationRightExecute ) и деавторизацию, нажав кнопку, и, нажав на другую, запустить вспомогательный инструмент от имени root. Обратите внимание, что этот вспомогательный инструмент может быть запущен от имени текущего пользователя или root, это сканер файловой системы (используйте right world, я не знаю точного термина для использования)

4. Я обновил свой ответ, пожалуйста, смотрите мое предложение выше. Если это решение кажется невозможным для вашего текущего проекта, пожалуйста, подробно объясните, почему вы так считаете, и я изменю его, чтобы оно лучше соответствовало вашим потребностям.

5. Спасибо, что уделили время моей проблеме — высоко ценю! Я постараюсь использовать только один вспомогательный инструмент как можно скорее.