Запуск аутентификации openid c на основе кода состояния восходящего потока - PullRequest
0 голосов
/ 12 марта 2020

Я использую lua-resty-openidc для реализации веб-интерфейса, который находится перед моей бэкэнд-системой.

Бэкэнд предоставляет REST API, защищенный заголовком Authorization, содержащим JWT. Веб-интерфейс управляет сеансом и отправляет веб-пользователей поставщику удостоверений, если им необходимо войти в систему. Когда веб-пользователь имеет сеанс, веб-интерфейс должен найти JWT, добавить его в заголовок авторизации и прокси-запрос к бэкэнду. - довольно стандартный материал.

К сожалению, мой бэкэнд не проводит четкого различия guish между publi c и частными ресурсами. Например, у него могут быть ресурсы с URL-адресами:

  • /api/public/0
  • /api/public/1
  • /api/private/2
  • /api/private/3

Позволяет запрашивать /api/public/{0,1} без заголовка авторизации, но /api/private/{2,3} требует авторизации. Фронтенд должен как-то с этим справиться. ( Примечание: Упомянутые выше URL-адреса упрощены, реальные не соответствуют шаблону и не могут быть легко перечислены.)

Основная проблема в том, что интерфейс может не сообщайте из URI запроса, должен ли он вызывать логин . Он должен быть реактивным, передавать запрос на сервер и проверять код ответа. Код 401 должен заставить клиента войти в систему, но любой другой ответ должен быть возвращен как есть.

Из-за этого я не могу поместить свои auth logi c в блок access_by_lua, так как они запускаются в фазе доступа до того, как запрос был отправлен в апстрим (бэкэнд).

Я попытался перевести мои логи c в фазу контента используя body_filter_by_lua блок:

location /api {
  set $session_storage shm;
  proxy_set_header X-Forwarded-Host  $http_host;
  proxy_pass https://backend;

  body_filter_by_lua_block {
    if ngx.status == ngx.HTTP_UNAUTHORIZED then
      ngx.log(ngx.INFO, 'Upstream returned a 401! Triggering auth flow')

      local opts = {
        discovery = 'https://login-server/.well-known/openid-configuration',
        scope = 'openid',
      }

      local res, err = openidc.authenticate(opts)
      if err or not res then
        ngx.status = ngx.HTTP_UNAUTHORIZED
        ngx.header.content_type = 'text/html';
        ngx.log(ngx.ERR, err)
        ngx.say("Forbidden")
        ngx.exit(ngx.HTTP_UNAUTHORIZED)
      end

    end
  }
}

… Но это не с ошибками (показано ниже). Кажется, я слишком поздно в жизненном цикле обработки запросов для установки заголовков и файлов cookie:

*194 [lua] body_filter_by_lua:5: Upstream returned a 401! Triggering auth flow while sending to client, client: 10.255.1.2, server: , request: "GET /api/private/2 HTTP/1.1", upstream: "https://backend/api/private/2", host: "frontend.example.org"

*194 [lua] openidc.lua:1363: authenticate(): Error starting session: Attempt to set session cookie after sending out response headers. while sending to client, client: 10.255.1.2, server: , request: "GET /api/private/2 HTTP/1.1", upstream: "https://backend/api/private/2", host: "frontend.example.org"

*194 attempt to set ngx.status after sending out response headers while sending to client, client: 10.255.1.2, server: , request: "GET /api/private/2 HTTP/1.1", upstream: "https://backend/api/private/2", host: "frontend.example.org"

Можно ли выполнить openidc.authenticate() в фазе содержимого из Nginx обработка запросов?

Есть ли лучший подход, который я должен использовать?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...