How to limit access to google app engine flask endpoints to just application code (or app engine service accounts)

非 Y 不嫁゛ 提交于 2020-08-10 23:06:06

问题


Currently building an app on app engine standard environment, with python 3.7 and the flask framework. I need to schedule some tasks which will require the app to run several sensitive endpoints periodically.

I want to limit access to these endpoints to the application itself, preventing (non-admin) users from accessing these. In the Python 2 version of app engine, it is possible by specifying login: admin in the app.yaml file like so:

# app.yaml for google app engine standard env python 2

handlers:

  - url: /this_is/my_protected/endpoint
    script: main.app
    login: admin

However, in the Python 3.7 incarnation of the app engine environment, this is no longer possible.

I understand that it may be necessary to do the authentication in the main.py file of my flask app, but I'm not certain where to start. I already have firebase auth working, and the app is authenticating users fine for several user facing endpoints. However I am not certain how to go about authenticating my own app-engine application (or possibly the service account) to run several of its own endpoints. I've tried checking the docs, but they're either sparse, or I simply can't find the information I require.

Is there a straightforward way to accomplish this?


回答1:


As suggested in a comment, here's my simplified (simplistic?) solution to make it such that specific flask end points in google app engine are only accessibly by application code or app engine service accounts. The answer is based on the documentation regarding validating cron requests and validating task requests.

Basically, we write a decorator that will validate whether or not X-Appengine-Cron: true is in the headers (implying that the end point is being called by your code, not a remote user). If the header is not found, then we do not run the protected function.

# python
# main.py

from flask import Flask, request, redirect, render_template

app = Flask(__name__)

# Define the decorator to protect your end points
def validate_cron_header(protected_function):
    def cron_header_validator_wrapper(*args, **kwargs):
        # https://cloud.google.com/appengine/docs/standard/python3/scheduling-jobs-with-cron-yaml#validating_cron_requests
        header = request.headers.get('X-Appengine-Cron')
        # If you are validating a TASK request from a TASK QUEUE instead of a CRON request, then use 'X-Appengine-TaskName' instead of 'X-Appengine-Cron'
        # example:
        # header = request.headers.get('X-Appengine-TaskName')
        # Other possible headers to check can be found here: https://cloud.google.com/tasks/docs/creating-appengine-handlers#reading_app_engine_task_request_headers

        # If the header does not exist, then don't run the protected function
        if not header:
            # here you can raise an error, redirect to a page, etc.
            return redirect("/")

        # Run and return the protected function
        return protected_function(*args, **kwargs)

    # The line below is necessary to allow the use of the wrapper on multiple endpoints
    # https://stackoverflow.com/a/42254713
    cron_header_validator_wrapper.__name__ = protected_function.__name__
    return cron_header_validator_wrapper


@app.route("/example/protected/handler")
@validate_cron_header
def a_protected_handler():
    # Run your code here
    your_response_or_error_etc = "text"
    return your_response_or_error_etc


@app.route("/yet/another/example/protected/handler/<myvar>")
@validate_cron_header
def another_protected_handler(some_var=None):
    # Run your code here
    return render_template("my_sample_template", some_var=some_var)


来源:https://stackoverflow.com/questions/61959706/how-to-limit-access-to-google-app-engine-flask-endpoints-to-just-application-cod

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!