ぶちのブログ

競プロとCTFが趣味なWebエンジニアのアウトプットの場

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認証をかけないようにした。