带有OpenID的App Engine remote_api [英] App Engine remote_api with OpenID

查看:104
本文介绍了带有OpenID的App Engine remote_api的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近试图将我的应用引擎应用切换为使用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,认证流程似乎如下所示:


  • 提示用户输入Google凭据

  • 将凭据发布到 https:/ /www.google.com/accounts/ClientLogin

  • 从响应正文中解析 auth 标记
  • >
  • 将令牌传递给 https://myapp.appspot.com/_ah/login

  • 在响应中设置 ACSID Cookie集
  • 传递 ACSID 在后续需要授权的请求中使用cookie



  • 我找不到很多关于新的OpenID支持的文档,尽管以下是我写的测试应用程序,了解工作原理:

    app.yaml:

     处理程序:
    - url:/ remote_api
    脚本: $ PYTHON_LIB / google / appengine / ext / remote_api / handler.py
    登录名:admin
    - url:/.*
    脚本: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是%s%(user.user_id(),
    users.is_current_user_admin()))
    else:
    self.redirect(users.create_login_url('/' ,无,
    'https://www.google.com/accounts/o8/id'))

    在Google帐户和联合登录之间翻转我的授权模式,我发现了一些事情:



    那么使用联合登录时remote_api发生了什么?如果我们使用的是默认的appengine_rpc.HttpRpcServer,它会忠实地遵循顶部所述的相同的Google帐户认证流程,只有应用程序不再考虑由/返回的 ACSID cookie。 _ah / login是有效的,所以既然你还没有通过身份验证,你会得到一个302重定向到OpenID登录页面/_ah/login_required。



    我不知道正确的解决方案在这里似乎它需要一个API更新。也许尼克或其他Google员工中的一员可以称重。



    现在,这里有一个很好的解决方法:


    • 打开您的应用程序的联合登录名

    • 确保您在为控制台脚本调用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:

    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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆