Basic認証とBearer Tokenを同時に使おうとしてハマった話
TL;DR
Basic認証とBearer Tokenは、同じAuthorizationリクエストヘッダを使うため、(少なくとも単純な実装では)同時には使うことができない。
ハマったこと
internal API通信にBearer Tokenを用いているWebアプリケーションにおいて、staging環境にBasic認証をかけていた場合に、staging環境で403エラーが出て通信が失敗した。
もう少し詳細な構成
AWSインフラを使っている。ALBの前にCloudFrontを噛ませてあり、アプリケーション側でBearer Tokenによる認証を実装した。さらにstaging環境においてはCloudFront側でAWS lambdaを用いたBasic認証を実装していた。
検証
curlとncコマンドで検証した。裏でncコマンドを使い、
nc -l 8888
でサーバーを立て、別タブで
curl http://localhost:8888
などとして、リクエストを送った。
Basic認証を使った場合
# request側 curl http://hoge:fuga@localhost:8888 # server側 GET / HTTP/1.1 Host: localhost:8888 Authorization: Basic aG9nZTpmdWdh User-Agent: curl/7.54.0 Accept: */*
Bearer Tokenを使った場合
# request側 curl http://localhost:8888 -H "Authorization: Bearer ACCESS_TOKEN" # server側 GET / HTTP/1.1 Host: localhost:8888 User-Agent: curl/7.54.0 Accept: */* Authorization: Bearer ACCESS_TOKEN
両方同時に使った場合
# request側 curl http://hoge:fuga@localhost:8888 -H "Authorization: Bearer ACCESS_TOKEN" # server側 GET / HTTP/1.1 Host: localhost:8888 User-Agent: curl/7.54.0 Accept: */* Authorization: Bearer ACCESS_TOKEN
となり、Basic認証が通らなくなる。curl --basic -u hoge:fuga http://localhost:8888 -H "Authorization: Bearer ACCESS_TOKEN"
などとしても同じ結果になる。
解決策
アプリケーション側ではstaging環境もproduction環境も同じ環境にしたかったため、CloudFront側で、本番でBearer Tokenを用いるpathに対しては場合分けし、Basic認証をかけないようにした。