SAML — Secure Assertion Markup Language. — используется для распределённой авторизации (federated authentication), когда сервис, к которому требуется получить доступ (Service Provider), обращается к другому сервису (Identity Provider) для того, что бы выполнить эту авторизацию.
Service Provider (SP): система, в которой требуется аутентифиция, в нашем случае это будет Jenkins
Identity Provider (IdP): система, вв которой хранятся пользователи, и которая выполняет их аутентификацию, в нашем случае Okta
Их взаимодействие и процесс аутентификации можно отобразить такой схемой:
Тут:
SAML Request: или authentication request, запрос аутентификации — создаётся SP для запроса аутентификации, передаёт пользователя
SAML Response: создаётся IdP, содержит информацию об уже аутентифицированном IdP пользователе и может содержать дополнительную информацию, например о группах этого пользователя
Кроме того, SAML-аутентификация может быть:
A Service Provider Initiated (SP-initiated): сервис, а нашем случае Jenkins, выполняет инициализацию аутентификации к IdP когда пользователь логинится в Jenkins
An Identity Provider Initiated (IdP-initiated): обратный вариант, когда сам SP (Okta) инициализирует аутентификацию в SP (Jenkins), когда пользователь кликает кнопку Jenkins из Okta
В этом посте рассматриваем именно Service Provider Initiated (но и Identity Provider Initiated будет работать тоже).
Стоит учесть, что SP никогда не взаимодействует напрямую с IdP — браузер пользователя является промежуточным звеном в коммуникации SP с IdP.
Содержание
Роль Service Provider
IdP генерирует SAML-ответ для SP, и в свою очередь SP должен проверить, что ответ получен от валидного IdP, а затем распарсить полученный ответ и получить необходимую информацию — имя пользователя, его группы и другие аттрибуты.
Для этого SP должен получить от IdP данные:
публичный сертификат IdP для проверки подписи
ACS Endpoint (Assertion Consumer Service URL), или просто «SP login URL» — ендпоинт, который SP передаёт IdP для получения SAML-ответов
IdP Login URL — ендпоинт IdP, на который SP будет отправлять SAML-запросы
Jenkins SAML for Okta
Основная идея подключения SAML в Jenkins является следующей:
пользователи хранятся в Okta
пользователи Okta объединены в группы
Jenkins использует Role-Based Strategy плагин, в котором настроены правила для групп, определяющие их доступы к различным джобам и привилегии в каждой из них
Jenkins SAML можно настроить двумя способами:
используя нативное приложение из набора Okta — проще, но нет поддержки групп пользователей, рассмотрим в части Okta native Jenkins SAML application
создать своё приложение в Okta, которое будет передавать custom attribute в виде имени группы пользователя, рассмотрим в Okta и своё приложения для Jenkins SAML
Настройку плагина Role-Based выполним позже, а в этом посте — рассмотрим настройку SAML для Jenkins в обоих вариантах.
Okta Community Created Jenkins SAML application
Настройка Okta
Переходим в Okta > Add app, находим Jenkins SAML:
Указываем URL Jenkins-а:
Переключаемся на Sign On:
Кликаем на View Setup Instructions — Okta уже сгенерировала все данные, которые будут использоваться нашим SP (Jenkins):
Переходим в Assignment, подключаем Jenkins SAML app к какому-либо уже существующему пользователю Okta:
Переходим в Jenkins.
Настройка SAML в Jenkins
Устанавливаем SAML плагин:
Переходим в Configure Global Security, переключаем авторизацию с Jenkins’ own user database на SAML:
Возвращаемся к Okta и странице с метаданными и копируем содержимое IdP Metadata:
Указываем их в Jenkins в настройках SAML:
Возвращаемся к Okta, в приложении копируем ссылку на Identity Provider metadata:
Задаём её в Jenkins как IdP Metadata URL:
Display Name Attribute и Group Attribute оставляем по умолчанию.
Проверяем: открываем в инкогнито наш Jenkins — происходит переадресация на Okta:
Логинимся, всё работает.
Okta и своё приложения для Jenkins SAML
Теперь настроим приложение в Okta, которое при SAML-аутентифицикации будет передавать в Jenkins ещё и группу пользователя из Okta, например группу DevOps:
Настройка Okta
Создаём новое приложение:
Задаём имя, логотип:
Далее, в Single sign on URL и Audience URI (SP Entity ID) указываем ACS Endpoint в виде http://dev.ci.example.com/securityRealm/finishLogin:
Для передачи группы пользователя Okta в Jenkins — добавляем кастомное поле в GROUP ATTRIBUTE STATEMENTS (OPTIONAL):
Name: Group
Name format: Basic
Filter — Matches regex и значение .*, что бы использовать все группы Okta
На следующпей странице — I’m an Okta customer adding an internal app, и Finish.
Не забываем про Assignments.
Далее — как в первом примере — кликаем View Setup Instructions, получаем IdP metadata и обновляем настройки Configure Global Security в Jenkins.
Копируем ссылку Identity Provider metadata:
Настройка SAML в Jenkins
Задаём её в Jenkins в IdP Metadata URL:
В Jenkins меняем Group Attribute с http://schemas.xmlsoap.org/claims/Group на просто Group:
Собственно, на этом всё.
Jenkins Role-based Security
Немного забегая наперёд (будет отдельный пост на эту тему) — пример использования Role-based Security и групп в Jenkins.
Пользователь и его группы в Okta:
Роли в Jenkins:
И группа DevOps которой присвоена роль test в Jenkins: