带有OpenID的App Engine remote_api [英] App Engine remote_api with OpenID
问题描述
我最近试图将我的应用引擎应用切换为使用openID,但我遇到了使用remote_api进行身份验证的问题。 remote_api的旧认证机制似乎不起作用(这是有道理的) - 我得到'urllib2.HTTPError:HTTP Error 302:Found',我认为它是appengine将我重定向到openid登录页面设置。
我想我错过了一些相当明显的东西。目前我的remote_api脚本有以下内容 -
remote_api_stub.ConfigureRemoteDatastore(app_id = app_id,path ='/ remote_api',auth_func = auth_func,servername = host,secure = secure)
其中auth_func是
def auth_func():
返回raw_input('用户名:'),getpass.getpass('Password:')
任何想法我需要提供给remote_api?我猜bulkloader也会遇到类似的问题。欢呼声,
科林
这真的很有趣。 / p>
查看remote_api,认证流程似乎如下所示:
auth
标记
ACSID
Cookie集
ACSID
在后续需要授权的请求中使用cookie
- 打开您的应用程序的联合登录名
- 确保您在为控制台脚本调用remote_api_stub.ConfigureRemoteDatastore时传递save_cookies = True
- 尝试控制台身份验证并获取302错误
- 通过应用程序的Web界面以管理员身份登录
- 在浏览器Cookie中, ACSID cookie myapp.appspot.com
查找并编辑您的本地〜/ .appcfg_cookies文件
- 替换myapp.appspot.com的ACSID cookie使用浏览器中的一个
下一次尝试使用remote_api时,它应该不会提示输入凭据。但是,每当cookie过期时,您都必须重复最后4个步骤。您可以在管理控制台中将过期时间从1天增加到2周,以最大限度地减少烦恼。玩得开心!
I've recently tried to switch my app engine app to using openID, but I'm having an issue authenticating with remote_api. The old authentication mechanism for remote_api doesn't seem to work (which makes sense) - I'm getting a 'urllib2.HTTPError: HTTP Error 302: Found', which I assume is appengine redirecting me to the openid login page I've set up.
I guess I'm missing something fairly obvious. Currently my remote_api script has the following in it -
remote_api_stub.ConfigureRemoteDatastore(app_id=app_id, path='/remote_api', auth_func=auth_func, servername=host, secure=secure)
where auth_func is
def auth_func():
return raw_input('Username:'), getpass.getpass('Password:')
Any ideas what I need to supply to remote_api? I guess similar issues would be encountered with bulkloader too. Cheers,
Colin
This was a fun one.
Looking at remote_api, the flow for authentication seems to be something like this:
- Prompt the user for Google credentials
- Post the credentials to https://www.google.com/accounts/ClientLogin
- Parse the
auth
token out of the response body - Pass the token to https://myapp.appspot.com/_ah/login
- Grab
ACSID
cookie set in the response - Pass the
ACSID
cookie in subsequent requests that require authorization
I couldn't find a lot of documentation on the new OpenID support, though Nick's blog entry was informative.
Here's the test app I wrote to see how things work:
app.yaml:
handlers:
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin
- url: /.*
script: test.py
test.py:
class MainPage(webapp.RequestHandler):
def get(self):
user = users.get_current_user()
if user:
self.response.out.write("Hi, %s!<hr>admin is %s" % (user.user_id(),
users.is_current_user_admin()))
else:
self.redirect(users.create_login_url('/', None,
'https://www.google.com/accounts/o8/id'))
Flipping my auth mode between Google Accounts and Federated Login, I noticed a few things:
- Admin users are correctly recognized by is_current_user_admin() with OpenID
- Mixing modes doesn't work. With authentication set to Google Accounts, calling create_login_url with a federated_identity throws a NotAllowedError
- An
ACSID
cookie is still produced at the end of the login process, only it comes from /_ah/openid_verify instead of /_ah/login
So what's happening with remote_api when using Federated Login? If we're using the default appengine_rpc.HttpRpcServer, it's dutifully following the same Google Account authentication process described at the top, only the app no longer considers the ACSID
cookie returned by /_ah/login to be valid, so since you're still unauthenticated, you get a 302 redirect to the OpenID login page, /_ah/login_required.
I dunno what the right solution is here. Seems like it would require an API update. Maybe Nick or one of the other Googlers can weigh in.
For now, here's a hacky workaround:
- Turn on Federated Login for your app
- Make sure you're passing save_cookies=True when calling remote_api_stub.ConfigureRemoteDatastore for your console script
- Attempt console authentication and get the 302 error
- Login as an admin via your app's web interface
- In your browser cookies, find the ACSID cookie for myapp.appspot.com
- Find and edit your local ~/.appcfg_cookies file
- Replace the ACSID cookie for myapp.appspot.com with the one from your browser
The next time you try to use remote_api, it should work without prompting for credentials. You'll have to repeat the last 4 steps every time the cookie expires, though. You can bump the expiration from 1 day to as high as 2 weeks in the admin console to minimize the annoyance. Have fun!
这篇关于带有OpenID的App Engine remote_api的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!