当通过 "flask run" 和 Vim 运行 代码时,Flask-Kerberos 会产生不同的结果

Flask-Kerberos yields different results when running the code via "flask run" and with Vim

简单地说,有一个基于 Flask-Kerberos example 的 Flask 应用程序,带有有效的密钥表文件 (os.environ['KRB5_KTNAME']='/path/to/file.keytab')。

这是我项目的工作树:

flask_kerberos_example\
    static\
        style.css
    templates\
        index.html
    example_pure.py
    config.py
    .flaskenv

这里是'example_pure.py'文件的内容:

from flask import Flask
from flask import render_template
from flask_kerberos import init_kerberos
from flask_kerberos import requires_authentication
from config import Config

app = Flask(__name__)
app.config.from_object(Config)

@app.route("/")
@requires_authentication
def index(user):
    return render_template('index.html', user=user)

if __name__ == '__main__':
    init_kerberos(app, hostname='Server.l.s.d')
    app.run(host="0.0.0.0", port=5000)

这里有一个'config.py'

import os
import base64
from dotenv import load_dotenv

basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir, '.flaskenv'))

class Config(object):

    # Setup Secret Key for Application
    SECRET_KEY = os.environ.get('SECRET_KEY') or str(base64.b64encode('you-will-never-guess'.encode("utf-8")))

这是一个 '.flaskenv'

FLASK_APP="example_pure.py"
FLASK_RUN_HOST="0.0.0.0"
FLASK_RUN_PORT=5000

当我使用 F9 通过 vim 执行此代码时,我得到了所需的输出

浏览器(http://Server.l.s.d:5000/

Flask Kerberos Example

It worked, I think you are username@L.S.D

命令

(venv) User@Server:~/.../flask_kerberos_example$ vim

 * Serving Flask app "example_pure" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
a.b.c.d - - [08/Jul/2021 09:35:19] "GET / HTTP/1.1" 401 -
a.b.c.d - - [08/Jul/2021 09:35:19] "GET / HTTP/1.1" 200 -
a.b.c.d - - [08/Jul/2021 09:35:19] "GET /static/style.css HTTP/1.1" 304 -

但是,当我使用 flask run 启动 Flask 应用程序时,我没有看到完全相同的结果。

浏览器(http://Server.l.s.d:5000/

Internal Server Error

The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.

命令

(venv) User@Server:~/.../flask_kerberos_example$ flask run

 * Serving Flask app "example_pure.py"
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
a.b.c.d - - [08/Jul/2021 09:37:28] "GET / HTTP/1.1" 401 -
[2021-07-08 09:37:28,023] ERROR in app: Exception on / [GET]
Traceback (most recent call last):
  File "/home/user/venv/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/user/venv/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/user/venv/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/user/venv/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/user/venv/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/user/venv/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/user/venv/lib/python3.7/site-packages/flask_kerberos.py", line 106, in decorated
    rc = _gssapi_authenticate(token)
  File "/home/user/venv/lib/python3.7/site-packages/flask_kerberos.py", line 70, in _gssapi_authenticate
    rc, state = kerberos.authGSSServerInit(_SERVICE_NAME)
TypeError: argument 1 must be str, not None
a.b.c.d - - [08/Jul/2021 09:37:28] "GET / HTTP/1.1" 500 -

正如我所见,Flask 对 _SERVICE_NAME 变量表示不满。我不明白是否必须在 '.flaskenv''config.py' 中设置它,不是吗?看起来这个问题与我之前的问题部分重叠:

有人可以向我解释什么可能是问题以及为什么我得到不同的结果吗?

当您使用 flask run 时,它 将您的应用作为模块导入 ,因此 __name__ 将不等于“__main__” ,因此 init_kerberos() 永远不会被调用,也永远不会在 flask-kerberos 中设置 _SERVICE_NAME 全局变量。

此外,一般来说,我会建议切换到 flask-gssapi,因为它以更清晰的方式编写并且不依赖于全局状态,并且因为它基于 python-gssapi而不是旧的和几乎无人维护的 pykerberos。