App Engine 开发服务器中的 HTTP 身份验证

发布于 2024-08-02 07:58:35 字数 197 浏览 2 评论 0原文

我想设置 App Engine 开发服务器,以便其他人可以预览。

在此之前我真正想做的是为该站点提供的任何 URL 启用 HTTP 身份验证。我不希望任何人在没有通过该阶段的情况下访问该服务。当然,我可以在我正在开发的应用程序中构建自己的 HTTP 身份验证,但这不是一个完美的解决方案,因为在部署应用程序时我不需要该功能。

有什么好的办法解决吗?

I want to setup the App Engine Dev Server, so that it's available to other people for a preview.

What I'd really like to do before that is enable HTTP authentication for any URL served from that site. I don't want anyone to access the service without passing that stage. I could, of course, build my own HTTP authentication into the app I'm developing, but that's not a perfect solution, because I don't need that feature when the app is deployed.

Is there any good way to solve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南风几经秋 2024-08-09 07:58:35

您使用的是 Java 还是 Python?

如果您使用 Python,则可以使用现有的 WSGI 中间件来处理 HTTP 基本身份验证。以下是一些选项:

Are you using Java or Python?

If you're using Python, you can use existing WSGI middleware to handle HTTP basic auth. Here are some options:

囚我心虐我身 2024-08-09 07:58:35

将应用程序部署到 appengine 服务器,但使用与最终在生产中使用的应用程序 ID 不同的应用程序 ID。这样,您就不必开发任何额外的身份验证机制,也不必担心开发应用程序服务器处理多个用户负载的能力如何。

Deploy the app to the appengine servers, but use a different app id than the one you will eventually use in production. That way you don't have to develop any extra authentication mechanism, and you don't have to worry about how well the dev app server will handle multiple users worth of load.

雾里花 2024-08-09 07:58:35

不要让 dev_appserver 可供公开访问。它不是为此而设计的,而且也不安全。仅举一个问题,任何访问者都可以访问 yourhost/_ah/admin/ 并弄乱您的数据存储,并且丢失理论的身份验证建议不会阻止它。

如果您绝对必须这样做,请将 Apache 或其他 Web 服务器设置为反向代理,实施身份验证并阻止对 /_ah URL 的访问。然而,Peter 建议将其部署到 App Engine,这是一个更好的建议。

Don't make the dev_appserver publicly accessible. It's not designed for it, and it's not secure. To name just one problem, any visitor can go to yourhost/_ah/admin/ and mess with your datastore, and the auth suggestions by lost-theory won't prevent it.

If you absolutely must do this, set up Apache or another webserver as a reverse proxy, implementing authentication and blocking access to /_ah URLs. Peter's suggestion of deploying it to App Engine is a much better one, however.

雪花飘飘的天空 2024-08-09 07:58:35

这是我想出的一个相当可靠的实现

通过我的搜索,我在网上发现了大量草率/不完整的 GAE BasicAuth 实现。结果,我最终自己写了。这是迄今为止我能想到的最好/最简单的方法。

我认为让请求处理程序尽可能精简是一个“良好实践”。为了减少处理程序本身的样板文件和复制粘贴,我决定将身份验证作为装饰器来实现。要使用它,只需将装饰器附加到处理程序的 get/post/put/delete 方法即可。

例如:

from decorators import basic_auth

class Handler(webapp2.RequestHandler):
  @basic_auth
  def get(self):
    # load your page here

然后将装饰器添加到decorators.py:

import base64
import os
from webapp2_extras import security
import yaml

def basic_auth(func):
  def callf(webappRequest, *args, **kwargs):
    # Parse the header to extract a user/password combo.
    auth_header = webappRequest.request.headers.get('Authorization')
    # if the auth header is missing popup a login dialog
    if auth_header == None:
      __basic_login(webappRequest)
    else:
      (username, password) = base64.b64decode(auth_header.split(' ')[1]).split(':')
      if(__basic_lookup(username) == __basic_hash(password)):
        return func(webappRequest, *args, **kwargs)
      else:
        __basic_login(webappRequest)
  return callf

def __basic_login(webappRequest):
  webappRequest.response.set_status(401, message="Authorization Required")
  webappRequest.response.headers['WWW-Authenticate'] = 'Basic realm="Secure Area"'

def __basic_lookup(username):
  accounts_file = os.getcwd() + os.sep + 'app' + os.sep + 'accounts.yaml'
  stream = file(accounts_file, 'r')
  for account in yaml.load(stream):
    if account['username'] == username:
      return account['password']

def __basic_hash(password):
  return security.hash_password(password, method='sha1')

注意:这里使用双下划线前缀的函数在“装饰器”之外不可见' 模块。

在这种情况下,失败的登录尝试只会弹出另一个登录对话框,我使用存储在单独的 account.yaml 文件中的密码进行身份验证,并且密码以 SHA1 哈希形式存储。

编写的代码易于自定义:

  • 如果您需要将密码存储在其他地方(例如数据库),请修改__basic_lookup()
  • 如果您的密码是纯文本或使用不同方法编码,请修改__basic_hash()
  • 如果您希望对失败的登录尝试有不同的响应,请修改__basic_login()。例如防止暴力攻击的人为延迟或重定向。

Here's a pretty solid implementation I came up with

Through my search, I found tons of sloppy/incomplete implementations of BasicAuth for GAE online. As a result, I ended up writing my own. This is the best/simplest approach I have been able to come up with so far.

I consider it a 'good practice' to keep request handlers as thin as possible. To cut down on boilerplate and copypasta in the handlers themselves I decided to implement authentication as a decorator. To use it just attach the decorator to the handler's get/post/put/delete methods.

For example:

from decorators import basic_auth

class Handler(webapp2.RequestHandler):
  @basic_auth
  def get(self):
    # load your page here

Then add the decorator to decorators.py:

import base64
import os
from webapp2_extras import security
import yaml

def basic_auth(func):
  def callf(webappRequest, *args, **kwargs):
    # Parse the header to extract a user/password combo.
    auth_header = webappRequest.request.headers.get('Authorization')
    # if the auth header is missing popup a login dialog
    if auth_header == None:
      __basic_login(webappRequest)
    else:
      (username, password) = base64.b64decode(auth_header.split(' ')[1]).split(':')
      if(__basic_lookup(username) == __basic_hash(password)):
        return func(webappRequest, *args, **kwargs)
      else:
        __basic_login(webappRequest)
  return callf

def __basic_login(webappRequest):
  webappRequest.response.set_status(401, message="Authorization Required")
  webappRequest.response.headers['WWW-Authenticate'] = 'Basic realm="Secure Area"'

def __basic_lookup(username):
  accounts_file = os.getcwd() + os.sep + 'app' + os.sep + 'accounts.yaml'
  stream = file(accounts_file, 'r')
  for account in yaml.load(stream):
    if account['username'] == username:
      return account['password']

def __basic_hash(password):
  return security.hash_password(password, method='sha1')

Note: Double underscore prefixed are used here on functions that shouldn't be visible outside of the 'decorators' module.

In this case, a failed login attempt will simply popup another login dialog, I'm authenticating using a password that is stored in a separate accounts.yaml file, and the passwords are stored in a SHA1 hashed form.

The code is written to be easily customized:

  • Modify __basic_lookup() if you need your passwords are stored somewhere else (ex database).
  • Modify __basic_hash() if your passwords are plaintext or encoded using a different method.
  • Modify __basic_login() if you want a different response to a failed login attempt. Such as an artificial delay to prevent brute-force attacks, or a redirect.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文