Некоторое время назад нам нужно было решение для аутентификации с использованием единого входа между несколькими веб-службами. По крайней мере, в то время мы считали протокол OpenID слишком сложным и не были убеждены в том, что плагины Ruby on Rails для него. Поэтому мы разработали собственный протокол вместо реализации поставщика OpenID и потребителей OpenID.
У меня два вопроса:
Разве плохо было не создавать
наш собственный поставщик OpenID и настройка
наши потребители OpenID принимают только это?
Публичный логин или регистрация не
позволили и мы хотели сохранить
простая аутентификация.
Можете ли вы определить критическую ошибку или уязвимость в следующем дизайне?
Если вы, как коммуна, можете одобрить этот проект, я рассмотрю возможность извлечения этого кода в плагин Ruby on Rails.
Пожалуйста, посмотрите на блок-схему и диаграмму последовательности .
подробности:
Поставщик аутентификации ("AP"):
- Центральная служба, которая содержит все данные
о пользователях.
- В этой настройке существует только один «AP».
- Возможно наличие нескольких «AP», но это не должно относиться к этому контексту.
- «AP» знает каждое «S» заранее.
Клиент аутентификации (служба "S"):
- Существует несколько внутренних и внешних веб-сервисов.
- Каждый сервис заранее знает «AP» и его открытый ключ.
Актер («А»):
- Конечный пользователь, который аутентифицируется
сама с AP по логину и паролю
- Может запрашивать непосредственно любой URI "S" или "AP" до ее входа в систему
Соединения между "A", "S" и "AP" защищены HTTPS.
Кратко описана логика аутентификации:
Это описание графической блок-схемы и диаграммы последовательности, которые были связаны в верхней части этого поста.
1) Поставщик авторизации "AP"
- «AP» отправляет HTTP-запрос POST «сервер-сервер» на «S», чтобы получить одноразовый номер.
- «AP» генерирует токен аутентификации.
- Токен аутентификации - это объект XML, который включает:
- срок годности (через 2 минуты),
- ранее запрошенный одноразовый номер (для предотвращения воспроизведения),
- идентифицирующее имя "S" (токен для Service_1 не подходит для Service_2),
- информация о конечном пользователе.
- Токен аутентификации зашифрован с помощью AES256, а ключ шифрования и вектор инициализации подписаны личным ключом RSA точки доступа.
- Результирующие строки («data», «key» и «iv») сначала кодируются в Base64, а затем в URL, чтобы их можно было доставить в строке запроса URL.
- Конечный пользователь "A" перенаправлен по HTTP на службу "S" (запрос HTTPS GET).
2) Сервис "S"
- Получает токен аутентификации в параметрах URL от пользовательского агента.
- Расшифровывает токен аутентификации с помощью предварительно общего открытого ключа AP.
- Принимает один токен аутентификации только один раз (токен содержит одноразовый номер, который действителен только один раз).
- Проверяет, что идентифицирующее имя в токене аутентификации соответствует имени службы.
- Проверяет, не истек ли токен аутентификации.
Примечания:
Это не проблема, если кто-то еще может расшифровать токен аутентификации, поскольку он не содержит конфиденциальной информации о пользователе. Однако крайне важно, чтобы никто кроме AP не смог сгенерировать действительный токен аутентификации. Следовательно, используется пара ключей RSA.
Закрытый ключ RSA используется только для подписи токена, поскольку он не может зашифровать данные, длина которых превышает фактическую длину ключа. Поэтому AES используется для шифрования.
Поскольку токен аутентификации доставляется как HTTP-запрос GET, он будет сохранен, например, в файле журнала Apache.Использование одноразового одноразового номера и даты истечения срока действия должно минимизировать вероятность повторной атаки.Для запроса POST потребуется страница HTML с формой, которая автоматически отправляется Javascript, поэтому используется GET.
Служба "S" генерирует одноразовый номер только в межсерверном API-запросе.Поэтому запросы на генерирование без аутентификации не должны представлять DoS-уязвимости.