App Engine remote_api with OpenID

前端 未结 3 1542
时光说笑
时光说笑 2021-02-04 13:07

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\

相关标签:
3条回答
  • 2021-02-04 13:20

    This is definitely an issue... mark your interest in getting Google to fix this by starring the ticket at http://code.google.com/p/googleappengine/issues/detail?id=3258 and feel free to add any of your workarounds there.

    On a related note, we also recognize that the docs are somewhat sparse, so I'm working on an article which hopefully fills-in some of those holes... stay tuned and keep your eyes open at http://code.google.com/appengine/articles

    0 讨论(0)
  • 2021-02-04 13:29

    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!

    0 讨论(0)
  • 2021-02-04 13:38

    Here's a workaround you can use until there's a more permanent solution in place.

    0 讨论(0)
提交回复
热议问题