我正在尝试在ec2上设置反向代理,以使用nginx通过自定义域提供对我的appengine应用的安全访问。它似乎工作正常,除非页面需要用户服务。它会重定向到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;
}
}
我的域名有一个指向ec2的CNAME。
===
我找到了解决方法。仍然希望更简单,并希望得到反馈。
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的代理服务,用户服务似乎也能正常工作。 ACSID cookie现在位于mydomain.com上,并通过代理发送到appengine。
appspot域仍然会向精通技术的用户展示,但这不是我主要担心的问题。我的目标是通过https提供服务并将我的自定义域保留在网址栏中,并且使用我的自定义域服务于无SSL的用户数据时更安全。由于整个交易都是通过https进行的,因此我认为这不会比使用没有SSL的mydomain.com更新会话cookie。无论如何,即使没有这个计划,任何其他跨站点攻击都会起作用。
我仍然不确定为什么mydomain.com/_ah/conflogin?state=blah失败并需要这种解决方法。
答案 0 :(得分:0)
你的解决方法为我解决了问题 - 谢谢!
这是我提出的代码,适用于陷入同样情况的其他人。这是一些特定于站点的东西被拔出,因此可能需要进行一些调整才能使其正常工作。 cookie是SACSID因为我使用的是https;我认为它将是httpID的ACSID。
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正在处理tarun2000描述的步骤(5)