Автоподписание ЭЦП при работе с iPad

5 4

При работе с Администрацией одного из районов Астраханской области столкнулись с такой проблемой, а точнее задачей. Глава администрации района работает на iPad и хотел бы подписывать документы ЭЦП через веб-доступ Directum. Но функция подписи документов при работе через iPad оказалась не доступна.

Натолкнувшись на статью «Автоподписание в типовых маршрутах» (http://club.directum.ru/post/Avtopodpisanie-v-tipovykh-marshrutakh.aspx) возникло решение настроить автоподписание документов на сервере.

Для решения задачи в типовом маршруте «Согласование официальных документов», который используется администрацией для отправки документов на подпись Главе, были внесены следующие изменения:

  • В блоке «Подпись документа ЭЦП руководителя высшего звена» в качестве исполнителя задачи вместо секретаря был указан параметр «Руководитель высшего звена» (т.е. параметр, в котором указывается Глава администрации). Это было сделано для того, чтобы задача подписания ЭЦП приходила непосредственно Главе администрации.
  • Для блока «Подпись документа ЭЦП руководителя высшего звена» добавили следующий код для события «После запроса параметров»:

 

// Инициализация
  Параметры = Work.WorkflowParams
  ДокументИнф = Параметры.ValueByName("ПисьмоИсходящее").Value
  Руководитель = Work.Info.Performer
  // Если результат выполнения блока - "Подписано", то проверить наличие ЭЦП
  // руководителя
  Результат = Work.ExecutionResult.Code
  если Результат == Sender.Results.ValueByName('Подписано').Code                         
   // Найти последнюю действующую версию документа
    Документ = ДокументИнф.Document
    НомерДействВерсии = GetNumVersionEDoc(Документ; EDOC_VERSION_ACTIVE_STAGE_CODE)
    если НомерДействВерсии >= 0
     // Если нашли подходящую версию, то проверяем подписи
      Подписано = CheckUserSignOnEDoc(Документ; Руководитель.Name; НомерДействВерсии)
    иначе
      Сообщение = 'Должна быть хотя бы одна действующая версия документа!'     
      Raise(СоздатьИсключение('EDIRNoActiveVersion'; Сообщение; ecWarning)) 
    конецесли 
    если не Подписано
      //проверяем,  осуществляется ли доступ через веб и является ли исполнителем задания - Глава
      если IsWebRuntimeContext() and Руководитель.ID == 12345 // для идентификации пользователя используется его ИД
        Document=Документ
        VersionNumber = НомерДействВерсии - 1
        SignType = stApproving
  
        //Подписать документ
        //Инициализация переменных
        CertificateFound = False
        CertificateForSignInfo = nil
        //Получить список сертификатов
        CertificateList = ServiceFactory.GetUserECertificateList(CurrentPerformerUser)
        //Получить первый сертификат
        CertificateList.Reset
        // Пока не достигнут конец списка сертификатов или сертификат не найден
        while not (CertificateList.EOF or CertificateFound)
          //Получить информацию о сертификате
          CertificateForSignInfo = CertificateList.Value
          //Проверить тип электронного сертификата: сертификат, предназначенный
          //для подписания ЭЦП (ctSignature),  или сертификат, предназначенный для подписания
          //ЭЦП и для шифрования (ctSignatureEncode), и, что данный сертификат используется по умолчанию
          CertificateFound = ((CertificateForSignInfo.CertificateType = ctSignature) or
          (CertificateForSignInfo.CertificateType = ctSignatureEncode)) and
          CertificateForSignInfo.IsDefault
          //Если сертификат не удовлетворяет условиям выше, присвоить переменной    CertificateForSignInfo пустой указатель
          if not CertificateFound
            CertificateForSignInfo = nil
          endif
          //Перейти к следующему элементу списка сертификатов
          CertificateList.Next
        endwhile
        //Проверить на пустой указатель: если информация о сертификате не  найдена, выдать сообщение пользователю
        Assert(not VarIsClear(CertificateForSignInfo); Format('У пользователя"%s" отсутствует сертификат для подписания'; CurrentPerformerUser.Name))
        //Получить сертификат из БД из компоненты "Пользователи" (открытый ключ)
        Certificate = CertificateForSignInfo.ECertificate
        //Получить права доступа пользователей к документу
        AccessRights = Document.AccessRights
        //Проверить права текущего пользователя на подписание ЭД
        AccessRights.CheckSign()
        // Получить версию для подписания
        Version = Document.Versions.Values(VersionNumber)
        //Получить список ЭЦП для ЭД. Если ЭД не подписан, список пуст
        ListECP=Version.Signatures
        //Получить первую подпись ЭД
        ListECP.Reset
        //Проверить, может соответствующая версия уже подписана соответствующим пользователем соответствующим типом подписи
        AlreadySign = FALSE
        foreach ECP in ListECP
          if ECP.Author.ID = CurrentPerformerUser.ID and ECP.SignatureType = SignType
            AlreadySign = TRUE
          endif 
        endforeach
        if Not AlreadySign
          //Загрузить сертификат из личного хранилища
          Certificate.Thumbprint = Certificate.Thumbprint
          //Подписать версию ЭД за себя
          Version.Sign(Certificate; SignType)
        endif  
      иначе      // если доступ осуществляется не через веб или пользователь с ИД не равным 12345, то подписать надо документ вручную
        Сообщение = 'Необходимо подписать последнюю действующую версию документа!'     
        Raise(СоздатьИсключение('EDIRLastVersionNoSigned'; Сообщение; ecWarning))
      конецесли      
    конецесли
  конецесли

Таким образом, из статьи «Автоподписание в типовых маршрутах» (http://club.directum.ru/post/Avtopodpisanie-v-tipovykh-marshrutakh.aspx) был заимствован код, из которого были убраны некоторые строки, в т.ч. функции, открывающие диалоговые окна (в режиме веб-доступа интерактивные окна не функционируют). Также добавлена проверка, ведется ли работа через веб-доступ и от имени конкретного пользователя (Главы администрации в нашем случае), чтобы для всех остальных пользователей блок работал в обычном режиме (когда необходимо самим ставить ЭЦП на документы).

Теперь для Главы администрации, когда он работает через iPad, приходит задание о подписании документа ЭЦП, и когда он нажимает на кнопку «Выполнить» - «Подписано», документ автоматически подписывается на сервере от его имени.

Отредактировал Алексей Пестерев, 06.03.2013 в 15:15
5
Авторизуйтесь, чтобы оценить материал.
Алексей Пестерев

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

Если просто в реестре, то тут есть дыра в безопасности. Тем более, когда идет речь о подписи министра. 

Людмила Пицина

в дальнейшем планируется использовать Rutoken, пока в режиме тестирования функционала хранение ключа в происходит реестре

Антон Посаженков

А можно ли Автоподписать документ в событии завершения блока или в Блоке Сценарий?

Михаил Тарасов

Для этого, закрытый сертификат должен быть установлен на сервере WorkFlow. 

Но, в этом случае он уязвим, так как в теории воспользоваться им может не только хозяин ключа...

Авторизуйтесь, чтобы написать комментарий