はじめに
みなさん、こんにちは!
アジャイル事業部の土井田です。
この記事は「もくもく会ブログリレー」 30日目 の記事です。
今回飛び入りでブログリレーに参加させていただきました。
6/20(木)、6/21(金)に幕張メッセで開催された『AWS Summit Japan 2024』のアイレットブースで、産業用ロボットを使った工場IoTのデモを展示しました。
実はデモ環境の構築で、地味に苦労したところがありましたので今回これをご紹介します。
苦労したところ
展示会では産業用ロボットから収集したIoTデータに加え、ロボットの動画をKinesis Video Streamで配信し、Amazon Managed Grafanaのダッシュボードに稼働状況とライブ動画を表示しました。
また、ロボットの運転開始/停止等のイベントが発生した時、イベント前後の動画をポップアップで確認できる様にしました。
以下はデモ環境の構成図です。(主要な構成要素のみ記載しています。)
イベント前後の動画はAWS LambdaでAmazon Kinesis Video Streamから切り出してAmazon S3に格納していますが、苦労したポイントは、「Amazon S3に格納されたイベント動画をどの様にしてサインインしているユーザーのみ取得可能とするか」という所です。
解決方法
Amazon S3に格納されたコンテンツをセキュアに配信する方法として、以下を考えました。
方法 | メリット | デメリット |
アクセスするファイルの期限付きURLを利用する | AWSが提供するドメインを使用するため、ドメインやSSL証明書をを用意しなくて済む | 期限付きURLを発行するためのアプリケーションが必要となる。 期限の長さを考慮する必要がある。 |
Application Load Balancer (ALB)経由でAmazon S3へ接続し、ALBとAmazon Cognitoを連携し認証する | コーディング無しで実現可能 サインインしたユーザーのみアクセス可能 |
ドメイン、SSL証明書を用意する必要がある。 |
Amazon Managed GrafanaにはAWS IAM Identity Centerで認証しSSOでアクセスしていますが、色々調べる中、AWS IAM Identity CenterからAmazon CognitoへSAMLでフェデレーションサインインできることが判り、今回は後者の方法で解決しました。
認証周りの構成は以下のとおりです。
構築方法
構築方法を以下に示します。
ドメイン・SSL証明書の取得
インターネットから静的コンテンツへhttpsでアクセスできるようにするため、Amazon Route 53でドメインを取得し、AWS Certificate ManagerでSSL証明書を発行しました。
VPCの作成
以下の条件でVPCを作成しました。
- 名前タグ:自動生成
- IPv4 CIDR ブロック:192.168.0.0/24
- AZの数:2
- パブリックサブネットの数:2
- プライベートサブネットの数:0
AWSマネジメントコンソールでVPCを作成すると、プレビューを見ながら名前タグやサブネットの設定も行えるため、便利です。
セキュリティグループの設定
VPCにはALBとAmazon S3のエンドポイントを構築しますが、各々に設定する以下のセキュリティグループを用意しました。
- ALBに設定するセキュリティグループ:全てのIPアドレスから443ポート(https)へのアクセスを許可
- Amazon S3のエンドポイント設定するセキュリティグループ:VPCのセグメントから80ポート(http)へのアクセスを許可
Amazon S3エンドポイントの構築
VPCに以下のエンドポイントを構築し、上で作成した80ポート(http)へのアクセスを許可するセキュリティグループを設定しました。
- サービス名:com.amazonaws.ap-northeast-1.s3
- タイプ:Interface
ALBを構築する時に、エンドポイントのIPアドレスを設定する必要があるため、エンドポイントを構築後、各サブネットのIPアドレスを控えておくと良いです。
Amazon S3 バケットの設定
インターネットからALB経由でAmazon S3のコンテンツにアクセスできる様にするためには、バケット名をサブドメイン(例:sub.domain.com)と一致させる必要がありました。
また、バケットポリシーには以下を設定し、S3エンドポイントからのみアクセス可能としました。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Statement1", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": [ "arn:aws:s3:::バケット名", "arn:aws:s3:::バケット名/*" ], "Condition": { "StringEquals": { "aws:SourceVpce": "S3のVPCエンドポイントのID" } } } ] } |
ALBの構築
まず、ALBの配信先となるターゲットグループを設定します。
- グループの詳細の指定
ターゲットタイプの選択:IPアドレス
プロトコル・ポート:HTTP 80
成功コード:200, 307, 405 - ターゲットを登録
IPアドレス:Amazon S3 VPCエンドポイントのIPアドレス(2つ)
次に以下を指定してVPCにALBを構築しました。
- 基本的な設定
スキーム:インターネット向け - ネットワークマッピング
マッピング:VPCのAZ、サブネットを全て選択 - セキュリティグループ:「セキュリティグループの設定」でALB用に作成したもの
- リスナーとルーティング
リスナー プロトコル:HTTPS
デフォルトアクション:上で作成したターゲットグループを選択
デフォルトSSL /TLSサーバー証明書:「ACMから」を選択し、ACMに設定された証明書を選択
Route 53のAレコード追加
以下を指定してドメインにレコードを追加しました。
- レコード名:S3バケット名に設定したサブドメインの先頭
- レコードタイプ:A
- エイリアス:ON
- トラフィックルーティング先:以下を選択
Application Load BalancerとClassic Load Balancerへのエイリアス
アジアパシフィック(東京)
上で作成したALBのURLを指定
この段階で、認証無しでブラウザからS3の静的コンテンツにアクセスできます。S3にテスト用のhtmlファイルを置いて動作確認しました。
IAM Identity Centerのアプリケーション追加・Amazon Cognitoユーザープールの作成
IAM Identity CenterのAmazon Cognitoの設定では相互に設定内容を反映する箇所があり、2つのタブで各々の画面を開いて設定しました。
設定内容は以下のとおりです。
IAM Identity Centerのアプリケーション追加
以下を指定してアプリケーションを追加します。最後のアプリケーションメタデータにはユーザープールの値を設定する必要があるため、Amazon Cognitoでユーザープール作成後入力します。
- セットアップリファレンス:設定するアプリケーションがある
- アプリケーションタイプ:SAML 2.0
- 「IAM Identity Center SAML メタデータファイル」のリンクをクリックし、ファイルをダウンロード(Amazon Cognitoの設定で使用します)
- アプリケーションメタデータ:「メタデータ値をマニュアルで入力する」を選択し、以下を設定
アプリケーションACS URL:https://ユーザープールのCognito ドメイン/saml2/idpresponse
アプリケーション SAML 対象者:urn:amazon:cognito:sp:ユーザープールのID
作成したアプリケーションを選択し、以下のとおり属性マッピングを設定します。
形式 | ||
Subject | ${user:subject} | persistent |
${user:email} | basic |
アプリケーション作成後、このアプリケーションにアクセスできるユーザーを追加します。
Amazon Cognitoユーザープールの作成
以下を指定してユーザープールを作成します。
- プロバイダーのタイプ:フェデレーティッドアイデンティティプロバイダー
- Cognito ユーザープールのサインインオプション:Eメールのみ選択
- フェデレーティッドサインインのオプション:SAML
- 多要素認証:MFAなし
- セルフサービスのアカウントの復旧:OFF
- セルフサービスのサインアップ:OFF
- Cognitoアシスト型の検証および確認:メッセージを自動的に送信しない
- Eメールプロバイダー:CognitoでEメールを送信
- SAMLプロバイダー名:任意の名称
- SAMLメタデータドキュメント:IAM Identity Centerの設定画面でダウンロードしたファイルをアップロード
- SAMLプロバイダーとユーザープールの間で属性をマッピング:以下を入力
ユーザープール属性:email SAML属性:email - ユーザープール名:任意の名称
- ドメインタイプ:Cognitoドメインを使用する
- Cognitoドメイン:任意(ユーザープールのサブドメイン)を設定
- 最初のアプリケーションクライアント:パブリッククライアント
- アプリケーションクライアント名:任意の名称
- クライアントシークレット:クライアントのシークレットを生成する
- 許可されているコールバックURL:https://S3のバケット名に設定したサブドメイン/oauth2/idpresponse
- 認証フロー:ALLOW_REFRESH_TOKEN_AUTHのみ指定
- ID プロバイダー:Cognitoユーザープールを削除
- OpenID Connect のスコープ:OpenID、Eメールのみ指定
ALBのAmazon Cognito認証ルールの設定
ALBリスナーのルールに上で作成したAmazon Cognitoのユーザープールによる認証の設定を追加します。
参考にした記事
ALB、S3、PrivateLinkによる内部HTTPS静的ウェブサイトのホスティング
IAM Identity CenterとCognitoユーザープールの統合
まとめ
IAM Identity Center、Amazon Cognito、ALB、Amazon S3を連携することで、SSOによるセキュアな静的コンテンツ配信を実現できました。これにより、Amazon Managed Grafanaのみで実現が難しい部分を補うことが可能です。
次は動的なWebアプリケーションのSSO連携にもチャレンジしたいと思ってます。
明日の記事は、西田さんの「フロントエンドが苦手でも! StreamlitとGeminiで簡単生成AIチャットボット開発 」です。楽しみです。