【Amazon AppStream】ADFSでフェデレーション認証する方法(後編)

記事タイトルとURLをコピーする

本記事は後編です。
前編をご覧になりたい場合はこちらから読めます。

構築手順

AppStream にドメインを登録

AppStreamのインスタンスをドメイン参加させるため、AppStreamのディレクトリにドメインを登録します。

Appstream2.0画面からDirectory Configsを追加します。
AppStreamのインスタンスがドメイン参加する際のADアカウントを事前に用意してください。

  • Directory Name:ADのドメイン名を指定(NetBIOS形式)
  • Service Account Name:ドメイン参加用ADアカウント
  • Organizational Unit (OU):OUをオブジェクト識別名(DN)で指定
  • Certificate-Based Authentication :OFF(チェックしない)

AppStream にスタックを作成

ドメイン参加済みのスタックを作成します。
VPCにDHCPオプションセットをアタッチしたのは、AppStreamがドメイン参加する際にADの名前解決を行う必要があるからです。
イメージ作成時にドメインのDNSを設定してしまうと、ドメイン参加はできますがAWSサービスの名前解決ができなくなるため、DHCPオプションセットを利用してどちらも可能になるようにしています。

まずはフリートを作成します。
画面に従い設定を進めますが、フリート作成画面のネットワーク設定でドメインとOUを指定してください。
※AppStreamのディレクトリを同じドメイン、OUを指定してください。


次に、作成したFleetからStackを作成します。
画面に従って設定を進めますが、ADで認証する場合パスワードでのログインが必須になるので、[Stack user setting]の[Password sign in for Active Directory]にチェックが入っていることを確認してください。

スタックへのアクセス許可を持つロールを作成

スタックへのアクセス許可を持つロールを作成します。
SAMLレスポンスにこのロールの情報を追加することで、ADユーザにスタックへのアクセス許可が付与されます。

まずは、ロールにアタッチするポリシーを作成します。
名称は任意で問題ありません。
ポリシードキュメントには以下を入力します。
今回はスタックを指定していますが、スタックを指定しないロールも作成できます。
そちらについては別途解説します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "appstream:Stream"
            ],
            "Resource": [
                "arn:aws:appstream:us-east-1::stack/[stack_name]"
            ],
            "Condition": {
                "StringEquals": {
                    "appstream:userId": "${saml:sub}",
                    "saml:sub_type": "persistent"
                }
            }
        }
    ]
}


次に、ロールを作成します。
ロールの名称は「AWS-[AWSアカウントID]-」で始まる名称にしてください。

  • Trusted entity type:SAML 2.0 federation
  • SAML 2.0–based provider:前編で作成したIdentity providersを選択
  • Access to be allowed:Allow programmatic and AWS Management Console access
  • Permissions policies:作成したポリシーを選択
  • Role name:[任意の文字列]

ADFSの証明書利用者信頼にAWSのサインインページを登録

ADFSの証明書を利用して接続できるよう、AWSのサインインページを登録します。

ADFSの管理コンソールを立ちあげ、[ADFS]-[Relying Party Trusts]を右クリックして追加します。

データソースの選択画面で、AWSのメタデータファイルのURLを入力します。
接続エラーになる場合はブラウザからURLに接続し、ダウンロードしたメタデータをインポートしても大丈夫です。

https://signin.aws.amazon.com/static/saml-metadata.xml


次の画面では、任意の名称を設定します。

[access control policy]は[Permit everyone]を選択します。
画面下の項目のチェックはOFFのままにしてください。

証明書利用者信頼が作成できたら、証明書利用者の識別子にAWSのSAMLのURLを追加します。 作成した証明書利用者信頼のプロパティを開き、[Identifiers]タブにある[Relying party identifiers]に以下を追加します。

https://signin.aws.amazon.com/saml

SAMLレスポンスにロールの情報を追加

ここまでくれば構築はあと少しです!
ADアカウントのユーザオブジェクトの属性値を取得し、クレームルールで加工してSAMLのレスポンスに追加します。

追加するクレームルールは4つです。

  • Name ID
  • RoleSessionName
  • Get Active Directory Groups
  • Roles


作成した証明書利用者信頼を右クリックし、[Edit Claim Issuance Policy ...]をクリックしてください。
クレームルールの一覧から追加できます。

Name IDのクレームルールには以下を設定します。

  • Claim rule name:Name ID
  • Rule template:Transform an Incoming Claim
  • Incoming claim type:UPN
  • Outgoing Claim type:Name ID
  • Outgoing name format:Persistent Identifier
  • Pass through all claim value:選択


RoleSessionNameのクレームルールには以下を設定します。


Get Active Directory Groupsのクレームルールには以下を設定します。

  • Claim rule name:Get Active Directory Groups
  • Rule template:Send Claims Using a Custom Rule
  • Custom Rule:下記を設定(コピペでOK)
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"] => add(store = "Active Directory", types = ("http://temp/variable"), query = ";tokenGroups;{0}", param = c.Value);


Rolesのクレームルールには以下を設定します。
本ルールで作成したロール名をSAMLレスポンスに追加しています。

事前に、ADにAWS-[AWSアカウントID]-[ロール名]の名称のセキュリティグループを作成し、Appstreamを利用するADアカウントを追加します。
ちなみに、ユーザにはメールアドレスがセットされている必要がありますので、検証などで作成する場合は忘れないようにしてください。

ユーザオブジェクトの属性には参加しているセキュリティグループ名が列挙されますが、その中でAWS-[AWSアカウントID]-で始まるものを検索し、冒頭(AWS-[AWSアカウントID]-)を覗いた文字列を「arn:aws:iam::[AWSアカウントID]:saml-provider/[前編で作成したIdentity providers名],arn:aws:iam::[AWSアカウントID]:role/」の最後に付ける処理を行っています。

  • Claim rule name:Roles
  • Rule template:Send Claims Using a Custom Rule
  • Custom Rule:下記を設定(一部編集が必要)
c:[Type == "http://temp/variable", Value =~ "(?i)^AWS-"]
 => issue(Type = "https://aws.amazon.com/SAML/Attributes/Role", Value = RegExReplace(c.Value, "AWS-[AWSアカウントID]-", "arn:aws:iam::[AWSアカウントID]:saml-provider/[前編で作成したIdentity providers名],arn:aws:iam::[AWSアカウントID]:role/"));


すべて追加できたら、ADFSサービスを再起動し、設定を反映させます。

net stop adfssrv
net start adfssrv


補足-ADにセキュリティグループを作成

セキュリティグループの名称はAWS-[AWSアカウントID]-[ロール名]でなくても構いません。
例えば、セキュリティグループ名をappstream-01-[ロール名]にしたい場合は、ルールを以下のように記述してください。

c:[Type == "http://temp/variable", Value =~ "(?i)^appstream-01-"]
 => issue(Type = "https://aws.amazon.com/SAML/Attributes/Role", Value = RegExReplace(c.Value, "appstream-01-", "arn:aws:iam::[AWSアカウントID]:saml-provider/[前編で作成したIdentity providers名],arn:aws:iam::[AWSアカウントID]:role/"));

AppStream接続用のURLを作成

最後にURLを作成します。
以下のサイトからURLを生成できます。

jackstromberg.com

設定値はこちらを入力してください。(一部編集が必要)

ブラウザから接続

端末のブラウザに生成したURLを入力すると、接続できます!

まとめ

お疲れさまでした。
クライアントアプリから接続する方法などの小ネタを別ブログで配信予定ですので、よろしければそちらもご覧ください。