LoginSignup
1
0

More than 3 years have passed since last update.

API Gatewayを通してBasic認証を使う方法

Posted at

課題

今回は、単純なFlaskのAPIアプリを作って、全世界に公開したくないので、単純なユーザ・パスワード認証(BasicAuth)をかけたいなと思いました。
ZappaというAWS LambdaにDeployできるフレームワークを使って、Flaskのアプリは、AWS上にすぐにDeployとAPIの確認ができました〜。

APIには、プログラムからBasicAuthに必要なヘッダーを付けておけば無事にAPIとの通信ができました。

pythonのrequestsを使って、API叩く例:

from requests.auth import HTTPBasicAuth
requests.get('https://api.example.com/', auth=HTTPBasicAuth('user', 'pass'))

HTTPヘッダー例:

GET /private/index.html HTTP/1.1
Host: example.com
Authorization: Basic ABCEF1234567890abcdef

ただし、開発者が簡易にAPI参照できるように、OpenAPI(swagger)表示できるページも用意しました。
そこでブラウザから、ページをアクセスしてみると。。。ダメだ。


image.png

モダンブラウザは、BasicAuthのログインをダイアログをだしてくれるのですが、出てこない様子。
どうにか、API Gatewayから返される401 Unauthorizedのレスポンスヘッダーには、必要なWWW-Authenticate: Basicがないようです。

確認すると、Flask側から正しくWWW-Authenticate: Basicを返しているようですが、APIGatewayがそのヘッダーを消しているっぽい。

さって、API Gatewayからは、ブラウザのログインダイアログが表示されるように、401 UnauthorizedのレスのヘッダーにWWW-Authenticate: Basicを付けるようにしましょう。

HTTP/1.1 401 Authorization Required
Date: Wed, 11 May 2005 07:50:26 GMT
Server: Apache/1.3.33 (Unix)
WWW-Authenticate: Basic realm="SECRET AREA"
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=iso-8859-1

対策方法

もうしかして、UnauthorizedApiGatewayResponseだけでいくかなと思うのですが、今回は、FlaskのRequestへ流す前、CUSTOM Authorizerを導入して、BasicAuthヘッダーを確認するようにしています。

BasicAuth用の設定と関数のリポジトリにまとめたので、既存のAPIGateway(rest-api)により楽にBasicAuthを追加することができたかと思います。ここまでくるには、色々大変だったのですが、この手順で10分以内にほしいBasicAuth設定が終わるだろう。

  1. リポジトリ取得:

    git clone https://github.com/monkut/lambda-basicauth-authorizer.git
    
  2. 環境準備(完全にAWSCLIでの用意は可能かと思うのですが、一部はBOTO3で書いちゃいました):

    # pipenvでpython環境を用意
    pipenv install
    
  3. 環境変数を設定、CUSTOM Authorizerの関数を置いて、既存ApiGatewayのrest-apiを更新:

    RESTAPI_IDは、既存のものからこのコマンドで取得: aws apigateway get-rest-apis
    PROJECTID は、ユニーク性を保つためのものだけです(なんでも良い)

    export AWS_PROFILE={my profile}
    export BASIC_AUTH_USERNAME={YOUR USERNAME}
    export BASIC_AUTH_PASSWORD={YOUR PASSWORD}
    export PROJECTID={YOUR PROJECT IDENTIFIER}
    export RESTAPI_ID={既存のRESTAPI ID}
    # CUSTOM Authorizer用のBucketを用意
    make createfuncbucket
    
    # CUSTOM Authorizerの関数をDeployして、既存のREST-APIにインストール
    make deploy
    make install
    

これで、APIだけじゃなくて、ユーザ(人間)がブラウザ経由でUSER/PASSのログインできるようになりました〜

FlaskにBasicAuth処理を残すちゃいば、ちょっと重複するのですが、BasicAuthなので、残っていても大した処理時間がかからないだろう。

最近、BasicAuthを使って、zappa と組み合わせて、開発用のDUMMY APIを提供したりしています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0