Как использовать Reverse Proxy для SSL с AppEngine и использовать службу Users? - PullRequest
2 голосов
/ 20 марта 2012

Я пытаюсь настроить обратный прокси-сервер на ec2, чтобы обеспечить безопасный доступ к моему приложению appengine через пользовательский домен с использованием nginx. Кажется, работает нормально, за исключением случаев, когда страницы требуют обслуживания пользователей. Он перенаправляет на страницу входа в учетные записи Google, а затем переходит в домен appspot вместо моего пользовательского домена. Я знаю, что у appengine есть ssl в тестировании, но я бы хотел найти решение, которое смогу использовать сейчас. Можно ли это преодолеть или мне нужно будет создавать своих собственных пользователей?

Ниже приведена моя конфигурация:

server {
  listen 443;
  server_name <custom-domain>;

  keepalive_timeout 70;

  ssl on;
  ssl_certificate     /etc/nginx/cert/server.crt;
  ssl_certificate_key /etc/nginx/cert/server.key;
  ssl_session_timeout  30m;

  location / {
      proxy_redirect   off;
      proxy_pass       https://<appid>.appspot.com;
      proxy_set_header Host <appid>.appspot.com;

      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      proxy_intercept_errors off;
  }
}

В моем домене есть CNAME, указывающая на ec2.

===

Я нашел обходной путь. Все еще надеемся на более простой и был бы признателен за обратную связь.

1) Client hits https: //mydomain.com/blah which goes through EC2 proxy https://appid.appspot.com/blah
2) The client is redirected to the google login page, with continue set as /aa?continue=/blah
3) Client logs into Google Accounts and is then redirected to https: //appid.appspot.com/aa?continue=/blah
4) Client hits https: //appid.appspot.com/aa which serves a redirect to https://mydomain.com/sc?c=ACSID&continue=/blah where ACSID is the Google account session cookie read by the handler for /aa.
5) Client hits https: //mydomain.com/sc?c=ACSID&continue=/blah which sets the ACSID session cookie for the domain mydomain.com and redirects to https: //mydomain.com/blah based on a continue parameter in aa passed to sc

Ниже приводится мой web.xml

/ is publicly accessible
/aa is publicly accessible
/sc is publicly accessible
/* is restricted to logged in users

Ниже приведено ограничение в обработчиках (с некоторыми хитрыми URL):

/ --> if not logged in, redirect to login page continue=/aa
/aa --> if not logged in, redirect to login page continue=/aa
/sc --> if not logged in, redirect to login page continue=/aa
/* --> if not logged in, redirect to login page continue=/aa?continue=*

После этого служба пользователя работает нормально даже при работе через прокси-сервер с SSL. Файл cookie ACSID теперь находится на mydomain.com и отправляется через прокси-сервер appengine.

Домен appspot будет по-прежнему показывать технически подкованным пользователям, но это не моя главная проблема. Моя цель состоит в том, чтобы обслуживать через https и держать свой настраиваемый домен в строке URL-адреса и быть более защищенным с пользовательскими данными, так как они обслуживают без SSL с использованием моего настраиваемого домена. Поскольку вся транзакция выполняется по протоколу https, я не думаю, что это предоставляет файл cookie сеанса больше, чем использование mydomain.com без SSL. Любые другие межсайтовые атаки будут работать даже без этой схемы.

Я все еще не уверен, почему mydomain.com/_ah/conflogin?state=blah не работает и требует этого обходного пути.

1 Ответ

0 голосов
/ 17 февраля 2014

Ваш обходной путь решил проблему для меня - спасибо!

Вот код, который я придумал, для всех, кто застрял в такой же ситуации. Это с некоторыми специфичными для сайта вещами, поэтому, возможно, потребуется немного доработать, чтобы это заработало. Файл cookie SACSID, потому что я использую https; Я думаю, что это будет ACSID для http.

class CompleteLoginHandler(BaseHandler):
    def get(self):
        redirect_to=self.request.get('next', '/')
        if not redirect_to.startswith('/'): # don't allow redirects to another domain
            redirect_to = '/'
        session_id = self.request.get('SACSID', None)
        if session_id:
            self.response.set_cookie('SACSID', session_id)
        return self.redirect(redirect_to)

class PostLoginRedirectHandler(BaseHandler):
    def get(self):
        domain = self.request.headers.get('X-Forwarded-Host', None)
        if domain is None:
            # we are on the bare url; need to transfer the user -- and cookie
            sacsid = self.request.cookies.get('SACSID')
            next_url = config['domain'] + self.uri_for('complete_login', next=self.uri_for(route_name), SACSID=sacsid)
            return self.redirect(next_url)
        else:
            return self.redirect('/')

Здесь PostLoginRedirectHandler имеет дело с шагом (4), а CompleteLoginHandler имеет дело с шагом (5) описания tarun2000

...