шего ведома или даже при некоторых обстоятельствах подделать диалог, вы об этом можете даже не догадаться.
Доверие внутри периметра, безусловно, наиболее распространенная из встречавшихся мне в организациях форм. Они могут решить запустить этот трафик через HTTPS-протокол, но не более того. Не могу сказать, что это подходящий вариант! Боюсь, что для большинства организаций, в которых я видел использование данной модели, безоговорочная доверительность не являлась осознанным решением, скорее большинство их представителей просто не понимало существующих рисков.
Стандарт HTTP Basic Authentication позволяет клиенту отправлять имя пользователя и пароль в стандартном HTTP-заголовке. После этого сервер может проверить эти элементы и подтвердить, что клиенту разрешен доступ к сервису. Преимущество заключается в том, что это предельно понятный и повсеместно поддерживаемый протокол. Проблема в том, что отправка по протоколу HTTP весьма проблематична, потому что имя пользователя и пароль не отправляются в безопасном режиме. Любая промежуточная инстанция может просмотреть информацию, находящуюся в заголовке, и увидеть данные. Поэтому HTTP Basic Authentication следует использовать с привлечением протокола HTTPS.
При использовании HTTPS клиент получает твердые гарантии, что сервер, с которым он ведет обмен данными, является тем самым сервером, с которым клиент задумал связаться. Кроме этого, дается гарантия защиты от подглядываний за трафиком между клиентом и сервером или от манипуляций с полезной нагрузкой.
Серверу нужно управлять собственными SSL-сертификатами, что может стать проблематичным при управлении несколькими машинами. Некоторые организации берут на себя процесс выдачи сертификатов, что становится дополнительной административной и рабочей нагрузкой. Инструментальные средства, занимающиеся автоматизированным управлением этим процессом, еще не достигли достаточного совершенства, и заниматься процессом выдачи вам не стоит. Самостоятельно подписанные сертификаты аннулировать нелегко, и поэтому требуется глубже продумывать сценарии возникновения аварийных ситуаций. Посмотрите, нельзя ли обойтись без всей этой работы, постаравшись полностью избежать применения самостоятельно сделанных подписей.
Еще один недостаток выражается в том, что трафик, проходящий через SSL, не может быть кэширован обратными прокси-серверами, подобными Varnish или Squid. Это означает, что если вам нужно кэшировать трафик, то это следует сделать либо внутри сервера, либо внутри клиента. Положение дел можно исправить, если завершать SSL-трафик в балансировщике нагрузки и размещать кэш-память за этим балансировщиком.
Нужно также подумать о том, что случится, если используется готовое SSO-решение, подобное SAML, у которого уже есть доступ к именам пользователей и паролям. Хотим ли мы, чтобы наш основной сервис аутентификации использовал тот же набор учетных данных, позволяя иметь один процесс для их выдачи и отзыва? Мы могли бы сделать это посредством сервиса, общающегося с тем же самым сервисом каталогов, который поддерживает SSO-решение. В противном случае придется хранить имена пользователей и пароли самостоятельно внутри сервиса, но тогда появится риск продублированности поведения.
Единственное замечание: при таком подходе серверу известно лишь, что у клиента есть имя пользователя и пароль. Мы не имеем ни малейшего понятия, исходит ли эта информация от той машины, от которой мы ее ожидаем, — она может приходить от кого угодно, находящегося в нашей сети.
Если в качестве схемы аутентификации и авторизации вами уже используется SAML или OpenID Connect, этим можно воспользоваться и для взаимодействия между сервисами. Если используется шлюз, весь внутрисетевой трафик нужно будет также направлять через шлюз, но если каждый сервис справляется с интеграцией своими силами, этот подход должен работать просто замечательно. Преимущество заключается в использовании существующей инфраструктуры и получении возможности централизации всех ваших элементов управления доступом к сервисам в центральном сервере каталогов. Если же нужно предотвратить возможность атаки в пути следования данных, передачу все равно следует направлять через HTTPS.
У клиентов для прохождения аутентификации с помощью провайдера идентификации имеется набор учетных данных, который они и используют, а сервис для принятия решения по детализированной аутентификации получает эту информацию. Это означает, что вам нужны учетные записи для ваших клиентов, которые иногда называют учетными записями сервиса. Этот подход довольно часто используют многие организации. Но следует предупредить: если вы собираетесь создавать учетные записи сервисов, постарайтесь сузить рамки их использования. Продумайте возможность наличия у каждого микросервиса собственного набора учетных записей. Это упростит отзыв или изменение доступа в случае компрометации учетных данных, поскольку достаточно будет лишь аннулировать набор затронутых учетных данных.
Но есть еще два недостатка. В первую очередь, так же, как и при использовании Basic Auth, требуется обеспечить надежное хранение учетных данных: где должны находиться имя пользователя и пароль? Клиент должен найти безопасный способ хранения этих данных. Вторая проблема заключается в том, что некоторые технологии, имеющиеся в данной области для проведения аутентификации, требуют довольно утомительного программирования. В частности, SAML превращает реализацию клиента в довольно непростое дело. При использовании OpenID Connect выполняемые действия несколько проще, но, как уже говорилось, эта технология пока еще не имеет хорошей поддержки.
Еще один подход к идентификации клиента заключается в использовании возможностей протокола безопасности транспортного уровня (Transport Layer Security (TLS)), последователя SSL, для формирования клиентских сертификатов. Здесь у каждого клиента имеется сертификат X.509, используемый при установке связи между клиентом и сервером. Сервер может проверить аутентичность клиентского сертификата, предоставляя твердые гарантии надежности клиента.
Рабочие задачи по управлению сертификатами здесь еще более обременительны, чем при использовании сертификатов на стороне сервера. И дело не только в ряде основных проблем, касающихся создания большего количества сертификатов и управления ими, а скорее в тех сложностях, которые касаются самих сертификатов. И вы должны быть готовы к тому, чтобы потратить много времени на определение причин, по которым сервис не признает то, что, по вашему мнению, будет совершенно допустимым клиентским сертификатом. И тогда, если произойдет самое худшее, нужно еще взять в расчет сложность аннулирования и повторного выпуска сертификатов. Помочь сможет применение групповых сертификатов, но это не решит всех проблем. Эта дополнительная нагрузка означает, что вы будете присматриваться к использованию данной технологии при особой обеспокоенности о конфиденциальности пересылаемых данных или при отправке данных по сети, не находящейся под вашем полным контролем. Поэтому вы, к примеру, можете принять решение о безопасном обмене только теми данными, которые имеют для сторон особую важность при их отправке по Интернету.
Как уже говорилось, использовать Basic Authentication через обычный HTTP, если вы обеспокоены компрометацией имени пользователя и пароля, не очень разумно. Традиционной альтернативой служит направление трафика через HTTPS, но у этого способа имеется ряд недостатков. Кроме управления сертификатами, издержки HTTPS-трафика могут стать причиной дополнительной нагрузки на серверы (хотя, если честно, сейчас в таком случае влияние на нагрузку значительно меньше, чем было несколько лет назад), да к тому же имеются сложности с кэшированием такого трафика.
Альтернативный способ подписи запроса, который активно используется API-интерфейсами S3 компании Amazon и является частью OAuth-спецификации, — применение кода проверки подлинности сообщений на основе хеш-функции (HMAC).
При использовании HMAC тело запроса хешируется закрытым ключом и получившийся хеш отправляется вместе с запросом. Затем сервер использует собственную копию закрытого ключа и тело запроса для воссоздания хеша. При совпадении запрос принимается. Приятным обстоятельством является то, что, если где-нибудь на дистанции кто-то проведет какие-либо манипуляции с запросом, хеш не совпадет и сервер будет знать, что запрос был подделан. А закрытый ключ в запросе никогда не пересылается, поэтому он не может быть скомпрометирован в пути! Дополнительным преимуществом является то, что затем трафик может намного легче кэшироваться и издержки на генерирование хешей могут быть намного ниже, чем на обработку HTTPS-трафика (хотя у вас может сложиться и другое мнение).
У этого подхода есть три недостатка. Во-первых, как клиенту, так и серверу нужен общий секрет, который каким-то образом должен быть передан. Как осуществляется его совместное использование? Он должен быть жестко задан на обоих концах, но затем в случае компрометации этого секрета возникнет проблема аннулирования доступа. Если пересылать этот ключ по какому-то альтернативному протоколу, то нужно быть уверенным в том, что этот протокол также обладает весьма высокой степенью безопасности!
Во-вторых, это схема, а не стандарт, поэтому существуют разные способы ее реализации. В результате наблюдается явная нехватка хороших, открытых и практичных реализаций этого подхода. В общем, если этот подход вам интересен, то можете обратиться к дополнительным источникам информации, чтобы разобраться в различных способах его реализации. Я бы предложил просто посмотреть, как он реализован компанией Amazon для ее S3, и скопировать их подход, особенно в использовании рациональной функции хеширования с соответствующим длинным ключом, таким как SHA-256. Стоит также присмотреться к веб-маркерам в формате JSON — JSON web tokens (JWT), поскольку в них реализуется очень похожий подход, который, кажется, набирает обороты. Но при этом имейте в виду, что выполнить все правильно нелегко. Мой коллега работал с командой, которая, занимаясь собственной JWT-реализацией, пропустила одну булеву проверку и сделала недействительным весь свой код аутентификации! Надеюсь, со временем мы увидим реализации библиотек, более пригодные к повторному использованию.