背景
今MacOSで開発しているflaskアプリはapache基本認証が必要です。そして、ユーザを管理するために認証情報をflaskに渡さなければならないという状況です。
認証情報のユーザ名はデフォルトで渡されるので何もしなくてもいいですが、パスワードも欲しいなら以下の記事が参考になれるかもしれません。
実行環境:
macOS -> Ventura 13.4
Apache -> 2.4.54
Python -> 3.10.11
pip3 -> 23.1.2
flask -> 2.3.2
用意
apacheからの認証情報を確認するために、環境変数を出力するflaskアプリが必要です。
環境設定とwsgiファイルは私の前の記事と同じです。
https://qiita.com/pabitele/items/6aa9269bd3109fee4806
hello.py
from flask import Flask, request
app = Flask(__name__)
@app.route('/')
def display_env():
env_vars = ""
for key, value in request.environ.items():
env_vars += f"{key}: {value}<br>"
return env_vars
if __name__ == '__main__':
app.run()
これは環境変数を一行ずつ出力するflaskアプリです。
設定ファイルの中身
まず設定ファイルの中身を見てみましょう。
<VirtualHost *:80>
LoadModule wsgi_module /Users/rikanshin/.local/lib/python3.10/site-packages/mod_wsgi/server/mod_wsgi-py310.cpython-310-darwin.so "test"
WSGIScriptAlias / /Users/rikanshin/Desktop/flask/myapp/test.wsgi
WSGIPassAuthorization On
<Directory /Users/rikanshin/Desktop/flask/myapp>
Require all granted
</Directory>
<Location / >
AuthType Basic
AuthName "test basic auth"
AuthUserFile "/etc/apache2/basic-auth/passwords"
Require valid-user
</Location>
</VirtualHost>
基本認証の設定
<Location>の中身は基本認証設定です。
Locationの後は基本認証の適用範囲です。
AuthTypeは認証の種類、それを基本認証を指定します。
AuthName認証ダイアログのプロンプト情報を設定するためのディレクティブです。
AuthUserFileの後はユーザ名とパスワードのファイルのパスです。(後で作ります)
Require valid-userは認証成功したユーザだけアクセスできるという設定です。
まずユーザ名とパスワードのアカウントファイルを作りましょう。
ファイルの置く場所に移動して(私の場合は /etc/apache2/basic-auth)
htpasswd -c passwords(アカウントファイル名) test1(新規ユーザ名)
でファイルと最初のユーザを作ります。
次のようなものが出るはずです。
New password:
Re-type new password:
Adding password for user test1
二番目のユーザから次のコマンドでアカウントを作ります。
sudo htpasswd passwords(アカウントファイル名) test2(新規ユーザ名)
最後は
apachectl -t
でSyntax OKが出たらOK。
念の為サイトにアクセスして認証画面でログインして確認しましょう。
認証情報を渡す
もしユーザ名だけ欲しいなら以下のことをやらなくてもいいです。
環境変数のREMOTE_USERの値を参照することでOKです。
例の設定ファイルで
WSGIPassAuthorization On
という行があります。これは認証情報をwsgiアプリケーションに渡すための設定です。
詳細は以下となります。1
User Authentication
As is the case when using CGI scripts with Apache, authorisation headers are not passed through to WSGI applications. This is the case, as doing so could leak information about passwords through to a WSGI application which should not be able to see them when Apache is performing authorisation.
Unlike CGI scripts however, when using mod_wsgi, the WSGIPassAuthorization directive can be used to control whether HTTP authorisation headers are passed through to a WSGI application in the HTTP_AUTHORIZATION variable of the WSGI application environment when the equivalent HTTP request headers are present. This option would need to be set to On if the WSGI application was to handle authorisation rather than Apache doing it:
WSGIPassAuthorization On
If Apache is performing authorisation and not the WSGI application, a WSGI application can still find out what type of authorisation scheme was used by checking the variable AUTH_TYPE of the WSGI application environment. The login name of the authorised user can be determined by checking the variable REMOTE_USER.
WSGIPassAuthorization On を設定したら、用意したflaskアプリにアクセスすると
のような環境変数があるはずです。
そもそもあるもの:
REMOTE_USER はユーザ名
AUTH_TYPE は認証種類
WSGIPassAuthorization Onで渡されるもの:
HTTP_AUTHORIZATION は認証種類と"ユーザ名:パスワード"という文字列をbase64でエンコードしたものです。
ここは例としてユーザはtest1でパスワードはabcです。検証してみましょう。
> echo 'dGVzdDE6YWJj'| base64 -D
test1:abc
これで認証情報を渡すことができました。(パスワードを含めて)。
まとめ
今回apacheの基本認証の設定と認証情報をflaskに渡す方法を記録しました。
お疲れ様でした。