原稿執筆が追い込みの為に、すっかりとブログから遠ざかっていました@dkfjです。最近、モバイルアプリについて考えることが多いのですが、その中のテーマの1つがシステムの認証認可です。先日、JAWSUGのアーキテクチャ支部で、それをテーマに議論してきたので今時点の課題意識を整理しておきます。
当日の資料
www.slideshare.net
説明が何も書いていないので、これだけ見てもさっぱり解らないと思います。順を追って、説明します。
認証と認可
まず認証と認可の違いです。認証は本人性の確認であり、認可はリソースに対する利用権限の付与です。多くのシステムでは、認証と同時に認可を行いますが、本質的には別々の機能ですよねという話です。もちろん、1つのシステムの中で同時に実現することの問題もありません。
Cognitoを利用した認証と認可
AWSには、認証と認可の部分を簡単にできるサービスとしてCognitoがあります。認証プロバイダとしては、FacebookやTwitterなど外部の認証局を利用できます。OpenID Connectベースの独自の認証局を立てることや、DynamoDBを利用することも出来ます。Cognitoの特徴としては、認証/未認証それぞれに権限を与えることができることです。未認証ユーザには参照権限、認証ユーザには書き込み権限も与えるといったユースケースが考えられますね。
Cognitoを利用した認証と認可その2
Cognitoのそれぞれの役割を分割して説明しています。一時的な利用権限の付与が肝となります。また、IAMの設定で、どのリソースを利用可能かを制限できます。
AWSの認可とアプリケーションが必要とする認可
このページが、今回の一番のテーマです。AWSの認可とアプリケーションが必要とする認可は違うよねと言うことです。Cognito等で、DynamoDBに対する参照権限を与えたとすると、気を付けないとその認可の範囲が広くなりがちです。例えば、ユーザーデータをDynamoDBに入れていたとしたら、ユーザに与えてよい権限としては、自分のデータに関する部分です。特に2-Tier構成の場合、アプリ側でデータの絞込をするので特に注意が必要です。
ちなみにユーザーデータに絞っていえば、CognitoにはCognito Syncという機能があります。そちらの方に格納するのも1つの解です。ただし、イメージ的にはユーザーごとにSQLiteのローカルデータベースを持つようなイメージなので、システムの管理側でユーザーデータをコントロールするといった場合には使えません。
認可のコントロール例
認可のコントロール例の1つ目としては、その辺りの処理をLambdaにさせたら良いですよねというパターンです。図では、API Gatewayを介していますが、API Gatewayなしで直接Lambdaの2-Tierでも問題ありません。
認可のコントロール例 その2
二つ目は、API Gatewayの利用自体も認証済みのユーザに絞るという方法もあるという例です。APIの利用ユーザの認証代わりにAPIキーを使おうとする場合もあります。APIキーは、認証代わりに使っては駄目です。例えばモバイルの場合、APIキーをアプリに埋め込んで配布することになるので、アプリモジュールからAPIキーは抽出可能です。ということで、ちゃんとやる場合はCognito使うのが良いですよ。
認可のコントロール例 その3
最後の例としては、Lambda側でCognitoを利用する例です。ここの例では、Cognitoを使っていますが、IAMとAssumeRoleを組み合わせることで、より細かい制御もできます。またIAM Roleの制限数より多いIAM Userを使うということも考えられます。それ以外にも、AWSと離れて、LambdaがADやLDAPなどのユーザストアと会話をすれば色々なことが出来るよねと話していました。
ここでIAMを使うとAWSの制限がシステムの制限になってしまうので、個人的には避けたいなと思っています。ケースバイケースですが。
現時点での課題
認証と認可については、考えれば考える程に奥が深いです。共通のデータを見る場合は、シンプルな認可で充分です。機微な情報の場合は、もう少し厳密にコントロールする必要があります。ただ、あまり細かいことをしようとすると、そもそもLambdaではなく既存の認証フレームワークを使うほうが楽だよねとなります。今後、そういった部分に対応するAWSのサービスや、サードパーティ製のフレームワークが出てくるのではないかなと他力本願で考えています。