当托管在azure上时,Python Webapp无法访问templates文件夹中的登录页

2024-04-26 04:25:04 发布

您现在位置:Python中文网/ 问答频道 /正文

Python webapp无法从templates文件夹呈现login.html,导致内部服务器错误(500),尽管当我从本地系统运行flask应用程序时,它工作正常。 重定向uri在代码和azure门户中都设置为相同

通过故障排除,我知道在azure上无法创建auth_url,并且失败了

from flask import Flask,render_template,url_for,session,request,redirect
from flask_wtf.csrf import CSRFProtect
from flask_session import Session
from werkzeug.routing import BaseConverter
import msal,requests


csrf = CSRFProtect()
def page_not_found(e):
    return render_template('404.html'), 404

def csrf_token_expired(e):
    return render_template('400.html'), 400

def internal_server_error(e):
    return render_template('500.html'), 500


app = Flask(__name__, static_folder='static', template_folder="templates")
app.config.from_object("config.DevelopmentConfig")
app.secret_key='Fpparesnal'

Session(app)
#app.config['SECRET_KEY'] = 'the random string'



app.register_error_handler(404, page_not_found)
app.register_error_handler(400, csrf_token_expired)
app.register_error_handler(500, internal_server_error)
#app.config.from_object("config.DevelopmentConfig")
csrf.init_app(app)

from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)

@app.route("/home")
def home():
    """
    This view returns the landing/home page of the tool.
    """
    return render_template('home.html')


@app.route("/")
def index():
    if not session.get("user"):
        return redirect(url_for("login"))
    return render_template('home.html', user=session["user"], version=msal.__version__)

@app.route("/login")
def login():
    # Technically we could use empty list [] as scopes to do just sign in,
    # here we choose to also collect end user consent upfront
    print('Reached Login')
    session["flow"] = _build_auth_code_flow(scopes=app.config['SCOPE'])
    print(session["flow"]["auth_uri"],'auth_url')
    return render_template("login.html", auth_url=session["flow"]["auth_uri"], version=msal.__version__)

@app.route(app.config['REDIRECT_PATH'])  # Its absolute URL must match your app's redirect_uri set in AAD
def authorized():
    try:
        print('Reached Redirect path')
        cache = _load_cache()
        result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(
            session.get("flow", {}), request.args)
        if "error" in result:
            return render_template("auth_error.html", result=result)
        session["user"] = result.get("id_token_claims")
        _save_cache(cache)
    except ValueError:  # Usually caused by CSRF
        pass  # Simply ignore them
    return redirect(url_for("index"))

@app.route("/logout")
def logout():
    session.clear()  # Wipe out user and its token cache from session
    return redirect(  # Also logout from your tenant's web session
        app.config['AUTHORITY'] + "/oauth2/v2.0/logout" +
        "?post_logout_redirect_uri=" + url_for("index", _external=True))

@app.route("/graphcall")
def graphcall():
    token = _get_token_from_cache(app.config['SCOPE'])
    if not token:
        return redirect(url_for("login"))
    graph_data = requests.get(  # Use token to call downstream service
        app.config['ENDPOINT'],
        headers={'Authorization': 'Bearer ' + token['access_token']},
        ).json()
    return render_template('display.html', result=graph_data)


def _load_cache():
    cache = msal.SerializableTokenCache()
    if session.get("token_cache"):
        cache.deserialize(session["token_cache"])
    return cache

def _save_cache(cache):
    if cache.has_state_changed:
        session["token_cache"] = cache.serialize()

def _build_msal_app(cache=None, authority=None):
    return msal.ConfidentialClientApplication(
        app.config['CLIENT_ID'], authority=authority or app.config['AUTHORITY'],
        client_credential=app.config['CLIENT_SECRET'], token_cache=cache)

def _build_auth_code_flow(authority=None, scopes=None):
    return _build_msal_app(authority=authority).initiate_auth_code_flow(
        scopes or [],
        redirect_uri=url_for("authorized", _external=True))

def _get_token_from_cache(scope=None):
    cache = _load_cache()  # This web app maintains one cache per session
    cca = _build_msal_app(cache=cache)
    accounts = cca.get_accounts()
    if accounts:  # So all account(s) belong to the current signed-in user
        result = cca.acquire_token_silent(scope, account=accounts[0])
        _save_cache(cache)
        return result

app.jinja_env.globals.update(_build_auth_code_flow=_build_auth_code_flow)