Category: Amazon Cognito*


Amazon Cognito ユーザープールが SAML フェデレーションをサポート [パブリックベータ]

昨年、Amazon Cognito Identity に SAML フェデレーションのサポートを追加しました。この機能は SAML レスポンスから一時的な AWS クレデンシャル情報を取得できます。 Amazon Cognito Identity は API ベースのアプローチをサポートしており、AWS クレデンシャル情報を取得するためには、SAML IdP (Identity Provider) の SAML 応答を解析し、Amazon Cognito Identity API をコールします。

Amazon Cognito ユーザープールは、あなたのモバイルおよび Web アプリに、セキュアでスケーラブルなユーザーディレクトリを使用したサインアップおよびサインイン機能を追加します。本日、Amazon Cognito ユーザープールの SAML IdP (Identity Provider) フェデレーションをアナウンスできることを嬉しく思います。本機能はユーザーディレクトリに SAML IdP のユーザーをマッピングし、 SAML IdP でユーザーを認証後にユーザープールから標準認証トークンを取得します。ユーザープールは SAML 2.0 POST Binding エンドポイントをサポートします。これにより、クライアントは SAML アサーションレスポンスの解析が不要になり、ユーザープールはユーザーエージェント (訳注: Web ブラウザ等) を介して IdP から直接 SAML レスポンスを受信します。

SAML フェデレーション機能の一つとして、ユーザープールはアプリの代わりに service provider (SP) として機能します。ユーザープールはアプリの単一のアイデンティティ管理ポイントになります。そのため、アプリは複数の SAML IdP を統合する必要はなくなります。 Amazon Cognito コンソールを利用して複数の SAML IdP を追加し、属性のマッピングを定義することで、すぐに利用を開始できます。

(more…)

サーバレス JavaScript アプリケーションで SAML: Part I

このブログ記事は AWS の Richard Threlkeld, Gene Ting, Stefano Buliani によって AWS Compute Blog に投稿された「SAML for Your Serverless JavaScript Application: Part I」の翻訳記事です。

このブログ記事に掲載したコードや SAM テンプレートの全体は samljs-serverless-sample GitHub レポジトリにあります。手動でリソースを作成する事もできますが、GitHub レポジトリにある SAM テンプレートを使ってリソースを作成することを強くお勧めします。


SAML 認証連携を実現したくありませんか? AWS プラットフォームで使うことができる一時的なセキュリティ認証情報の発行を、短期間の SAML アサーションを交換で実現できます。

エンタープライズ Web アプリケーションを構築する時は、認証や認可が一貫して行われ業界のベストプラクティスに沿っている事が必須事項です。AWS では、ユーザに一意のIDを作成し、AWS のサービスにアクセスできる短期間の認証情報を使えるようにできる Amazon Cognito と呼ぶサービスを構築しました。これらの認証情報は、IAM ポリシーに基づくロールと関連付けて、異なるリソースへのアクセスを許可や拒否する事ができます。

この記事では、Amazon Cognito で SAML プロバイダと認証連携を行う異なる方式を紹介していきます。応用すると、異なるタイプの認証プロバイダ (IdP) と連携させることができます。Facebook、Twitterやその他のサードパーティのソーシャルメディアを IdP にする事もできます。Amazon Cognito のユーザプールと認証連携させ、独自のマネージドユーザディレクトリを作成することもできます。

例えば、ユーザが Active Directory Federation Services (ADFS) で認証する事ができる JavaScript アプリケーションを構築したいかもしれません。ユーザは AWS 認証情報で許可された範囲で API を呼び出して得た情報をアプリケーションに表示させたり、DynamoDB テーブルに書き込むことができます。AWS Mobileブログの記事「Announcing SAML Support for Amazon Cognito」では、新しい SAML 機能について Java、Android、iOS のサンプルコード付きで紹介しました。この記事では、ADFS フローのカスタマイズについて JavaScript のサンプルを交えて詳細に紹介します。

シナリオ

この記事では、クライアント側のフローを紹介します。SAML アサーションは Amazon API Gateway 経由で渡され、ブラウザ上のコードは Amazon Cognito Identity から直接認証情報を受け取ります。次回のブログ記事では、バックエンド側の処理を紹介します。SAML アサーションと認証情報は、AWS Lambda ファンクション内で処理でき、ビジネスロジックを実現するようカスタマイズしたり監査履歴を取ったりする事ができます。

このシナリオの全コードは SAM テンプレート含め、GitHub の samljs-serverless-sample レポジトリにあります。手動でリソースを作成する事もできますが、GitHub レポジトリにある SAM テンプレートを使ってリソースを作成することを強くお勧めします。

サーバレスのアーキテクチャとなっていますが、ADFS との連携は従来のコンピュート サービスである EC2 インスタンスのようなコンポーネントで置き換えることもできます。ADFS の用語や定義については「Claims-based identity term definitions」を参考にして下さい。

前提条件

このブログ記事では、ADFS が動作している環境が必要です。以下の事を実施して下さい。:

  1. AWS コンソールで ADFS との認証連携を設定。「Enabling Federation to AWS Using Windows Active Directory, ADFS, and SAML 2.0」を AWS CloudFormation テンプレートと共に参考にしてください。
  2. サインインページ(https://localhost/adfs/IdpInitiatedSignOn.aspx)からユーザ example\bob が ADFS-Dev と ADFS-Production の両方のグループとして認証出来ることを確認します。
  3. Amazon Cognito Identity のプールを作成します。

ADFS 設定の概要

チュートリアルを始める前に、幾つか AWS と SAML の設定を確認しましょう。まず、前提条件にある通り IAM ロールが作成されているかから確認して下さい。アプリケーション用に新しく IAM ロールと AD グループを作成してもかまいません。この記事では、「Enabling Federation to AWS Using Windows Active Directory, ADFS, and SAML 2.0」の記事の通り ADFS-Dev と ADFS-Production を利用します。

  1. IAM コンソールで、ロールを選択し ADFS-Ddev を選択し、信頼関係 (Trust Relationships) のタブを開き、以下のコードのようになっている事を確認します。:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "arn:aws:iam::YOURACCOUNTNUMBER:saml-provider/ADFS"
          },
          "Action": "sts:AssumeRoleWithSAML",
          "Condition": {
            "StringEquals": {
              "SAML:aud": "https://signin.aws.amazon.com/saml"
            }
          }
        }
      ]
    }

このポリシーは “ADFS” という SAML IdP で認証されたユーザがロールを引き受ける事を許可しています。また、ポリシーには条件が含まれており、SAML アサーション内の AudienceRestriction が https://signin.aws.amazon.com/ である事となっています。SAML アサーションは ADFS から AWS に HTTP POST で SAMLResponse というヘッダとして送られて来ます。前提条件に記載されている設定が実施済みであれば、ADFS コンソールでは以下のように設定されており、利用者(Ralying Party)の URL として AWS メタデータ URL が指定されています。詳細については、「認証レスポンスの SAML アサーションを設定する」を確認して下さい。



認証後、ADFS は利用者のアプリケーションに自動的にリダイレクトします。

上記のスクリーンショットでは、認証後の SAMLResponse の値を見るために Chrome を利用しました。「トラブルシューティングのためにブラウザで SAML レスポンスを表示する方法」に記載されているとおり、他のブラウザでも同様のことを行えます。SAMLResponse を貼り付ければ、Audience、Roles や Destination などの値を見ることができる “SAML Decoder” がインターネット上にあります。パート 2 のブロク記事では、これをプログラムで行う方法を紹介します。

ADFS からサーバレス Web サイトにリダイレクトし、Amazon Cognito に繋げる

この1つ目のブログのシナリオの方が難しくありません。多くの組織での要件にベストな流れとなっています。ユーザは ADFS で認証して Amazon Cognito から AWS 認証情報を受け取り、アプリの中でアクションを行えます。このサンプルアプリケーションは:

  1. ADFS で認証するログイン メカニズムを変更して取り出すことで、SAMLResponse ヘッダを取り出します。ユーザが S3 上に配置されたウェブサイトを訪問した際に、自動的にこの仕組みが行われます。
  2. ADFS-Dev ロールの信頼ポリシーを変更し、Active Directory の AWS-gDev グループのメンバであれば Amazon Cognio から一時的な認証情報を受け取れるようにします。
  3. ユーザのロールを選択するコードをアプリケーションの中に組み込みます。このブログ記事では、ADFS-Dev ロールを選択します。

参考までに、AWS Console への認証連携の場合 #3 と同様の内容は、ADFS のウェブページ IdpInitiatedSignOn.aspx からリダイレクトされた後にラジオボタンでロールをクリックして選択する事で実現されます。より詳しい内容については、セキュリティブログの「Enabling Federation to AWS Using Windows Active Directory, ADFS, and SAML 2.0」をご覧下さい。もしユーザが 1 つの Active Directory グループのメンバだけであれば、SAMLResponse には複数のロールが含まれておらず、その場合は #3 は省略されます。構成は以下の図のとおりとなります。

チュートリアル: ADDFS からサーバーレス Web サイトにリダイレクトし、Amazon Cognito に繋げる

まず、サーバレス Web サイトをセットアップし、認証情報を取得するログインフローを開始させます。シングル Web アプリを配置するのには S3 を使用します。

S3 バケットの作成

  1. S3 のコンソールで、「バケットを作成」を選択して一意なバケット名を入力します。以下の例では “serverlessweb” としますが、皆様は何か他の名前として下さい。
  2. バケットを作成後、詳細設定のページで「プロパティ」を選び、「バケットポリシーの編集」をクリックします。
  3. 以下のポリシーを設定して下さい。YOURBUCKETNAMEGOESHERE は置き換えて下さい。このポリシーは、バケットに入っている HTML や JavaScript などのファイルを誰でも GET リクエストを行えるようにします。Web サイトにアクセスすると Web ブラウザは GET リクエストを発行し、このポリシーがリソースの読み込みをユーザに許可します。
    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "PublicReadForGetBucketObjects",
              "Effect": "Allow",
              "Principal": "*",
              "Action": "s3:GetObject",
              "Resource": "arn:aws:s3:::YOURBUCKETNAMEGOESHERE/*"
          }
      ]
    }
  4. 「静的ウェブサイトホスティング」を選択し、「ウェブサイトのホスティングを有効にする」とします。フォームに「index.html」と「error.html」を入力します。

  5. 次に、HTML ファイルをバケットに追加して、https://YOURBUCKETNAME.s3-website-REGION.amazonaws.com をブラウザで開きページが見れるか確認します(YOURBUCKETNAME と REGION は読み替えて下さい。)。まずは以下の HTML をテンプレートとして使って下さい。
    <!DOCTYPE html>
    <html>
     <head>
      <title>
       Amazon Cognito SAML Example
      </title>
      <script src="aws-sdk.min.js">
      </script>
     </head>
     <body>
      <h1>
       Testing SAMLResponse
      </h1>
     </body>
    </html>
      
  6. JavaScript SDK から圧縮(Minify)されたバージョン aws-sdk.min.js をダウンロードして、HTML ファイルと同様にバケットに保存し、エラー無くロードできることを確認します。

(オプション) CloudFront ディストリビューションのセットアップ

次に進める前に、さらにもう1つセットアップしたいと思います。CloudFront ディストリビューションです。S3 静的 Web ホスティングに CloudFront やその他の CDN を使用することで、独自ドメイン名で SSL を使用することができるようになります。

API Gateway から HTTP サイトにリダイレクトする事もできるため強制ではありませんが、Web サイトや認証や認可のシステムはエンドツーエンドで HTTPS を使うべきです。以下がセットアップで行う内容です。

  1. CloudFront コンソールで、Web タイプのディストリビューションを作成します。
  2. 「Viewer Protocol Policy」には、「HTTPS Only」を選択します。
  3. 「Origin Domain Name」には S3 バケットを選択します。
  4. ベストプラクティス通り、「Restrict Bucket Access」を選択します。こうすることで、バケットが直接アクセスされることから守ることができます。これで CloudFront ディストリビューションのドメイン名で、サイトにアクセスできるようになると思います。

ログイン メカニズム

次に、ログイン メカニズムを構築します。

ウェブサイトではログインさせるために、ボタンを押させることも出来ますし、自動的に認証情報が有効かどうか確認してからログインのフローにリダイレクトをさせる事もできます。

この例では、2 つ目のアプローチを取ります。ユーザがページを訪れると JavaScript を使ってすぐに状態を確認し、初回の訪問であれば認証情報を入手するためにリダイレクトさせます。このページにはログインの流れの中で API Gateway から再度リダイレクトされても来るため、ログインの進捗に合わせ ADFS のログインページにリダイレクトさせるのと同様に、届いた SAMLResponse のデータをキャプチャする事も必要です。今回の例では、以下のような流れになります。:

function loginWorkflow(){
    var activelogin = sessionStorage.getItem('activelogin');
    if (activelogin=='inProgress'){                                   //ADFS login redirect from API Gateway
        var samlResponse = getParameterByName('SAMLResponse');
        sessionStorage.removeItem(‘activelogin’);
        if (samlResponse != null){
            getSamlCredentials(samlResponse.replace(/\s/g, ''));
        }
    }
    else if (activelogin === null) {                                 //First page visit. Redirect to ADFS login.
        var RPID = encodeURIComponent('urn:amazon:webservices');
        var result = 'https://localhost/adfs/ls/IdpInitiatedSignOn.aspx' + "?loginToRp=" + RPID;
        sessionStorage.setItem('activelogin', 'inProgress');
        window.location = result;
    }
    else {//Credentials exist, page refresh, etc.
        console.log('activelogin already exists in session and the value is ' + activelogin);
    }
}

上記では、ADFS IdP への呼び出しを始める時にセッション変数を設定し、SAMLResponse (getParameterByName() で取り出せる)と一緒にWeb サイトに戻って来た時には getSamlCredentials() 関数を呼び出します。

AWS が必要とする SAMLResponse 値は POST binding のみがサポートされていますが、S3 の静的ウェブサイトは、GET リクエストしか受け取ることができません。このため、JavaScript アプリケーションが ADFS からの SAMLResponse を受け取るために API Gateway を利用します。Lambda をプロキシとして利用し、SAMLResponse をクエリ文字列に入れて静的ウェブサイトにリダイレクトで戻ってこさせます。

Lambda 関数の設定

  1. Lambda のコンソールで、GitHub レポジトリにある /Scenario1/lambda/redirect/index.js を使って samlRedirect という名前の関数をランタイムは Node.js 4.3 で作成します。実行ロールにはログ保存のために CloudWatch Logs の権限だけが必要です。
  2. 基本的な実行ロールが既になければ、関数作成時に新しいロールを Lambda のコンソール上で作成する事ができます。
  3. LOG_LEVELREDIRECT_URL という名前の環境変数を作成し、LOG_LEVEL には info を REDIRECT_URL には S3 の静的ウェブサイトの URL(静的ウェブホスティングを有効にしている場合にはバケットのプロパティに表示されているエンドポイント、あるいは先程記載したオプションの CloudFront ディストリビューション設定をした場合はドメイン名)を設定します。

API Gateway 設定

  1. API Gateway のコンソールで、SAMLAuth あるいは何か似た名前を付けた API を作成します。
  2. リソース」 を選択し、「SAML」という名前の子リソースを作成します。
    lambdasamlone_7.png
  3. POST」メソッドを作成します。「統合タイプ」には「Lambda」を選択し、「samlRedirect」関数を指定します。「メソッドリクエスト」の「HTTP リクエストヘッダー」に「SAMLResponse」を設定します。
    lambdasamlone_8.png

先ほど作成した samlRedirect 関数では、クエリ文字列に SAMLResponse を付けた静的ウェブサイトの URL を location プロパティに設定します。リダイレクトが実行されるように、API Gateway が 302 ステータスコードを返すように設定します。

  1. メソッドレスポンス」でステータスコード 200 を削除し、302 を追加します。「レスポンスヘッダ」に「Location」を設定し、「レスポンス本文」には「コンテンツタイプ」に「application/json」、「モデル」に「Empty」と設定します。
    lambdasamlone_9.png
  2. 「統合レスポンス」で「メソッドレスポンス」のステータスが 200 のものを削除し、302 のものを追加します。レスポンスヘッダ「Location」の「マッピングの値」には「integration.response.body.location」を設定します。
    lambdasamlone_10.png
  3. Lambda 関数が SAMLResponse と RelayState を受け取れるように、「統合リクエスト」で「コンテンツタイプ」が 「application/x-www-form-urlencoded」の「本文マッピングテンプレート」を以下のように追加します。:

    {
    "SAMLResponse" :"$input.params('SAMLResponse')",
    "formparams" : $input.json('$')
    }
  4. 変更を保存します。
  5. /saml リソースで「アクション」から「CORS の有効化」を選択します。「CORS を有効にして既存の CORS ヘッダを置換」を行いします。

  6. アクション」から「API のデプロイ」を選択します。「ステージ」には「Prod」や似た名前を使用します。「ステージエディター」で、「SDK 生成」を選択します。「プラットフォーム」には「JavaScript」を選択し、「SDK の生成」を行い、どこかのフォルダに保存します。ADFS の設定に必要になるため、トップに表示されている「URL の呼び出し」をメモします。

ADFS リダイレクト設定

  1. ADFS のコンソールで、「利用信頼関係」にある Amazon Web Services のプロパティを開き、「利用者を自動的に更新する」の項目を無効(チェックしない)にします。
    lambdasamlone_11.png
  2. エンドポイント」のタブを開き、既にあるエンドポイントを編集します。「バインディング」は「POST」のままで、「URL」には API Gateway でデプロイした API の「URL の呼び出し」を入力します。URL の最後に 「/saml」を追加します。
    lambdasamlone_12.png
    これまで構築してきたことを復習します。:

    • Web ページはユーザが認証情報を持っていなければ、ADFS のログインページにリダイレクトします。
    • 認証に成功したら、ADFS は SAMLResponse を付けて Web ページにユーザを戻します(API Gateway 経由)。
    • SAMLResponse は元の Web ページにクエリ文字列の一部として渡されます。

    Amazon Cognito から認証情報を取得するには、JavaScript コードでこのクエリ文字列を取り出し getCredentialsForIdentity 呼び出しのパラメータの一部として渡す必要があります。

  3. Amazon Cognito の Federated Identities のコンソールで、前提条件でセットアップした認証プールを開きます。認証プールの ID を確認し、以下の JavaScript コードの先頭に利用するリージョン名と同様に記載します。
    const identityPool = 'YOURCOGNITOPOOLID';
    AWS.config.region = 'COGNITOREGION'; // Region
    
    AWS.config.credentials = new AWS.CognitoIdentityCredentials({
        IdentityPoolId: identityPool
    });
    
    var identityId = localStorage.getItem('cognitoid');
    if (identityId != null){
        console.log('Identity ID: ' + identityId);
        loginWorkflow();
    } else {
        console.log('Calling GetID');
        AWS.config.credentials.get(function(){
            console.log('Identity ID: ' + AWS.config.credentials.identityId);
            localStorage.setItem('cognitoid', AWS.config.credentials.identityId);
            identityId = localStorage.getItem('cognitoid');
            loginWorkflow();
        });
    }

このコードは、アプリケーションでユーザに Amazon Cognito で生成した一意の ID を付与する最初の部分です。その上で、クエリ文字列に SAMLResponse の値を入れて返させるために loginWorkflow() を呼び出します。

以下は Stack Overflow で紹介されているサンプルのユーティリティ関数で、クエリ文字列から特定の項目を取り出すためのものです。

function getParameterByName(name, url) {
    if (!url) {
      url = window.location.href;
    }
    name = name.replace(/[\[\]]/g, "\\$&amp;");
    var regex = new RegExp("[?&amp;]" + name + "(=([^&amp;#]*)|&amp;|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
}

これで Web ページは ADFS から BASE64 エンコードされた SAMLResponse を取得しました。これを Amazon Cognito に渡せば AWS 認証情報を取得することが出来ます。Cognito の getSamlCredentials() 関数は以下のコードで、loginWorkflow() から呼び出されます。:

function getSamlCredentials(samlResponse) {
    var role = 'arn:aws:iam::ACCOUNTNUMBER:role/ADFS-Dev';
    var params = {
        IdentityId: identityId,
        CustomRoleArn: role,
        Logins: {
            'arn:aws:iam::ACCOUNTNUMBER:saml-provider/ADFS' : samlResponse,
        }
    };

    cognitoidentity.getCredentialsForIdentity(params, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
            console.log('Credentials from Cognito: ');
            console.log(data.Credentials);
        }
    });
}

ARN にある ACCOUNTNUMBER は2つとも書き換える必要がある事に注意して下さい。今回は使用するロールがソースに直書きされています。もし、SAML クレームに複数のロールが入って返されないのであれば、このパラメータは省略することもできます。引き受けるロールを何かしらのロジックで選択するようにしたい場合もあると思います。このブログ記事のパート II ではクライアント側ではなくバックエンドでこれをできるようにする内容を含める予定です。

また、logins map にあるキーは IAM コンソールで作成した ADFS の IdP 登録の ARN で、値は samlResponse です。これもアカウント番号に書き換える必要があります。この情報により Amazon Cognito は SAMLResponse の値が信頼している対象の ADFS からのものであるか検証できます。

この時点でこのコードを試しても動作しません。Amazon Cognito の認証プールで、認証プロバイダとして SAML IdP を有効にする必要があります。

  1. Amazon Cognito の Federated Identities のコンソールで、プールを選択し、Authentication Providers までスクロールし、SAML を選択します。ADFS の IdP を示すチェックボックスを選択します。
  2. Save Changes をクリックします。
    lambdasamlone_13.png

次に、Amazon Cognito が有効な SAMLResponse アサーションを受け取った時に、ユーザがロールを引き受けられるように信頼ポリシーを変更します。Amazon Cognito は STSAssumeRoleWithWebIdentity API を呼び出してこれを実現します。

IAM のコンソールで、ADFS-Dev ロールの信頼ポリシーを以下のポリシーに編集します。(JavaScript コードのように適切な位置に Amazon Cognito のプール ID を挿入します。):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "YOURCOGNITOPOOLID"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "authenticated"
        }
      }
    }
  ]
}

これで Amazon Cognito の信頼ポリシーは設定できました。Web ページをテストして下さい。AWS サービスのリクエストへの署名に使える認証情報はコンソールログに (AccessKey, SecretKey, Token) の 3 つが含まれる形で “data” オブジェクトで出力されます。アプリケーションの共通のシナリオは、AWS_IAM 認証に設定された API Gateway のメソッド呼び出しを行うことです。認証情報は SDK のリクエストを使うことで渡す事ができます。上記の呼び出して指定したロールにその API を呼び出す権限があれば、メソッド呼び出しは成功します。

例えば、API Gateway で API を作成した場合、メソッドに AWS_IAM 認証を有効にできます。上記で指定されたロール(logins mapで指定)に、メソッド呼び出しの権限があることを確認して下さい。より詳しいことは、「API Gateway へのアクセスを IAM アクセス権限で制御する」をご覧下さい。API をデプロイした場合、SDK の生成を使ってそのステージの JavaScript SDK を生成してダウンロードできます。これからのメソッド呼び出しを Web ページに組み込む事ができます。より詳しいことは、「API Gateway で生成した JavaScript SDK を使用する」をご覧下さい。トピックの最後に、apigClientFactory.newClient コンストラクタにアクセスキーシークレットキーをどうやって渡すことができるか確認しましょう。

Amazon Cognito Identity は短期間だけ有効な認証情報(1 時間で無効になる)を利用するため、一時的なアクセスキー、シークレットキー、セッショントークンを、apigClientFactory.newClient コンストラクタに渡します。:

        var apigwClient = apigClientFactory.newClient({
        accessKey: data.Credentials.AccessKeyId,
        secretKey: data.Credentials.SecretKey,
        sessionToken: data.Credentials.SessionToken
    });

機能の動作確認ができる Web ページのコードは、GitHub レポジトリ内の /scenario1/website/index.html にあります。同じディレクトリにある configs.js ファイルを更新します。リージョン、Cognito Identity のプール ID、SAML IdP の ARN、ADFS-Dev ロールの ARN を変更します。SAM テンプレートを使って API Gateway に AWS_IAM 認証の MOCK エンドポイントを作成する事もでき、連携された認証情報が機能するか Web ページ上のテストボタンで確認する事ができます。

lambdasamlone_14.png

最後に

チュートリアルを通じて SAML 認証や Amazon Cognito を使った AWS 認証について深いレベルで理解する手助けになる事を願っています。まだ完了していなければ、少し時間をかけて頂き、GitHub レポジトリの samljs-serverless-sample にあるコードを実際に動かし確認して下さい。また感想についても教えてください。

このシナリオは最初のステップとして十分かもしれませんが、組織によってはより多くのことをする必要があるかもしれません。例えば、ロールの選択をユーザに任せたいやビジネスロジックに基づき独自の IAM 範囲を実装したい事もあるかと思います。このシリーズのパート 2 ではこれらをどのようにしたら実現できるかを見ていきたいと思います。

[訳注] このブログで紹介している方法では、ADFS におけるデフォルトの AWS の証明書利用者設定を変更します。そのため、同じ ADFS 環境で AWS のマネージメントコンソールへ認証連携してアクセスさせる事とは同時に実現できません。

原文: SAML for Your Serverless JavaScript Application: Part I (翻訳: SA 辻 義一)

新機能 – Amazon Cognito グループ、およびきめ細かなロールベースのアクセス制御

アプリケーションの構築における課題の 1 つは、ユーザー認証と管理に関する事柄です。この課題に直面しても、多くの開発者はアプリケーション用の別のユーザー ID と認証システムを構築したいとは考えていませんし、必要な場合を除いてユーザーにさらに別のアカウントを作成させたいとも思っていません。Amazon Cognito では、アプリケーションのデータとバックエンドシステムにアクセスするために、開発者がユーザーの ID、認証、および権限を簡単に管理できるようになっています。それに加えて、開発者がアプリケーションの異なるユーザーに異なる権限を割り当てるのを簡単にするサービス機能があればどんなによいでしょう。本日、Cognito ユーザープールがグループをサポートし、Cognito フェデレーション識別がきめ細かなロールベースのアクセス制御 (RBAC) をサポートするようになったことが発表されました。Cognito でのグループのサポートにより、開発者は異なるユーザータイプとアプリケーションの使用権限を表すグループを作成して、ユーザーのアプリケーションエクスペリエンスを簡単にカスタマイズできます。開発者は、グループからのユーザーの追加や削除、およびユーザーのセットに対してグループで権限を管理できます。権限に関しては、Cognito フェデレーション識別でのきめ細かなロールベースのアクセス制御 (RBAC) のサポートにより、開発者は異なる認証をされたユーザーに異なる IAM ロールを割り当てられます。これまで、Amazon Cognito ではすべての認証されたユーザーに対して 1 つの IAM ロールのみをサポートしていました。きめ細かな RBAC を使用すると、開発者はフェデレーティッドユーザーに異なる IAM ロールをマッピングすることができます。この機能は Facebook や Active Directory などの既存の ID プロバイダーと Cognito ユーザープールを使用したユーザー認証の両方で利用できます。

Cognito ユーザープールのグループ
新しい Cognito のグループの機能について調べる最善の方法は、Amazon Cognito コンソールで新しいグループを作成して、さまざまなグループタイプにユーザーを追加してみることです。Cognito - UserPoolCreateGroup   [my user pool]、[TestAppPool] を選択すると、[Users and groups] という更新されたメニュー項目があります。メニューオプションを選択すると、パネルに [Users] と [groups] の両方のタブが表示されます。新しいグループを作成するには、[Create Group] をクリックします。グループを作成するダイアログボックスが開きます。ここでは、AdminGroup という管理者ユーザー用のグループを作成します。グループの名前とグループの説明を記入し、優先順位を設定してグループを作成する準備ができました。優先順位の数値をグループに設定すると、複数のグループに割り当てられているユーザーに対して、どのグループの権限が優先して使用されるかが決定されます。優先順位の数字が低いほど、ユーザーが使用するグループの優先順位が高くなります。自分の [AdminGroup] の場合、このグループにゼロ (0) の優先順位を付けます。[Create group] ボタンをクリックして、自分のユーザープールグループを作成します。Cognito - CreateGroupDialog-s あとは、自分のユーザーをグループに追加するだけです。このテストアプリケーションプールでは、以下の図のように [TestAdminUser] と [TestUnregisteredUser] の 2 人のユーザーがいます。[TestAdminUser] を、新しく作成したグループに追加します。Cognito - Users ユーザーを AdminGroup ユーザープールグループに追加するには、[Groups] タブで自分の [AdminGroup] を選択します。AdminGroup の詳細画面の表示後、[Add users] ボタンをクリックすると、ユーザープール内のユーザーを表示するダイアログボックスが表示されます。このグループにユーザーを追加するには、追加するユーザー名の横にあるプラスのマークをクリックするだけです。ユーザーがグループに追加されたという確認を受け取ると、このプロセスは完了です。ウォークスルーからお分かりのように、開発者がユーザープール内にグループを作成することは簡単です。AWS マネジメントコンソール、API、および CLI を使用して、ユーザープール内のグループを作成および管理できます。開発者として、AWS 認証情報を使用してユーザープールのグループを作成、読み込み、更新、削除、およびリストすることができます。各ユーザープールには、最大 25 個のグループを含めることができます。さらに、ユーザープール内のグループからユーザーを追加または削除できます。また、グループに AWS IAM ロールを割り当てることによって、グループを使用して AWS のリソースへのアクセス許可をコントロールすることができます。Amazon API Gateway と組み合わせて Amazon Cognito を使用することによって、自分のバックエンドリソースへのアクセス許可をコントロールすることもできます。

Cognito - AddUsersAdminGroup - small

Cognito フェデレーション識別でのきめ細かなロールベースのアクセス制御
Cognito フェデレーション識別機能の、きめ細かなロールベースのアクセス制御 (Role-Based Access Control) を詳しく調べましょう。以降、これを RBAC と呼びます。RBAC について見てみる前に、Cognito フェデレーション識別機能の概要を確認しましょう。Cognito ID は、AWS アカウント認証情報を使用せずにアプリケーションから AWS リソースにアクセスするための、権限が制限されている一時的な認証情報のセットをユーザーに割り当てます。各ユーザーの権限は、お客様が作成する AWS IAM ロールを介して制御されます。この時点で、マネジメントコンソールの別のウォークスルーで RBAC について見ていきましょう。コンソールで [Cognito] サービスを選択したら、[Federated Identities] を選択します。RBAC を確認している間に稼働中の Cognito ユーザープールとフェデレーション識別を示すのが最善であると思うので、認証プロバイダーとして Cognito ユーザープールを使用する新しい ID プールを作成します。新しいユーザープールを作成するために、最初に ID プールの名前を入力し、認証されていない ID へのアクセスを有効にするチェックボックスをオンにします。次に、[Authentication Providers] の [Cognito] タブを選択して、TestAppPool ユーザープール ID とアプリケーションのクライアント ID を入力します。アプリケーションのクライアント ID を取得し、アプリケーションが Cognito ID プールを利用して関連付けられたユーザープールにアクセスするために、Cognito ユーザープール内にアプリケーション (アプリケーションクライアント) が作成済みである必要がある点に注意してください。Cognito - CreateIdentityPool ID プールの作成が済んだところで、Cognito ユーザープールの認証方法にロールベースのアクセスを割り当てましょう。異なるロールを割り当てる最も簡単な方法は、Cognito ID プールでルールを定義することです。各ルールは、ユーザー属性を指定するか、コンソールに表示されるようにクレームを指定します。クレームは、ルールによって一致し、特定の IAM ロールに関連付けられる、その属性のトークンの値です。RBAC の利点を真に示すためには、エンジニアリング部門のユーザーがオブジェクトを S3 に配置し、DynamoDB にアクセスできるテストアプリケーションの役割が必要になります。このロールを作成するために、まず S3、GetItem、クエリ、スキャンへの PutObject アクセスおよび DynamoDB への BatchGetItem アクセスが含まれるポリシーを作成する必要があります。このポリシーを TestAppEngineerPolicy と呼ぶことにします。前述のポリシーを作成した後で、このポリシーを活用する EngineersRole という名前の IAM ロールを作成します。この時点で、AWS リソースへのきめ細かなアクセスのできるロールがあるので、Cognito ID プールにもどります。[Edit identity pool] をクリックし、[Authentication providers] セクションをドロップダウンします。ID プールの認証プロバイダが Cognito ユーザープールであるため、[Cognito] タブを選択します。フェデレーティッド認証のきめ細かな RBAC を確立しているので、[Authentication provider] の [Authenticated role selection] セクションに注意を集中して、ルールを定義します。このセクションでは、ドロップダウンをクリックして、オプションの [Choose role with rules] を選択します。Cognito - AuthenticationProviderここで、クレーム (属性)、一致する値、特定の IAM ロール、EngineersRole のルールを設定します。たとえば、作成しているルールが特定の IAM ロール (例: EngineersRole) を、部門属性が「Engineering」として設定された Cognito ユーザープールで認証済みのユーザーに割り当てます。ルールに基づいている部門属性は、下の図に示すように、ユーザープール TestAppPool で作成したカスタム属性であることに注意してください。Cognito - CustomAttributes - smallこれで、この問題はクリアしたので、ルールの作成にもう一度注目します。クレームに関しては、前述のカスタム属性、部門を入力します。部門の値が、文字列「Engineering」と等しい場合にこのルールが適用されます。したがって、[Match Type] フィールドで [Equals match type] を選択します。最後に、ルールで一致する属性値に対する、実際の文字列値「Engineering」を入力します。ユーザーが部門属性に対して一致する値を持っている場合、認証情報を取得したときに EngineersRole IAM ロールを引き受けることができます。これを完了して、[Save Changes] ボタンをクリックすると、Cognito ユーザープールで認証済みの、エンジニアリング部門のユーザーがアプリケーションを使用している他の認証されたユーザーとは異なる権限を持てるルールが正常に作成されました。Cognito - AuthenticationRoleSelection Cognito ID プールで異なるロールに割り当てるルールの設定のウォークスルーを完了したので、きめ細かな RBAC について覚えておきたい重要なポイントをいくつか説明します。まず、最初に一致するルールが適用されるために、ルールはオーダーと IAM ロールで定義されます。次に RBAC を設定するには、ユーザープールにより割り当てられる ID トークンを介してルールを定義し、ロールを活用することができます。ID プールで設定された各認証プロバイダーに対して、最大合計 25 個のルールを作成できます。さらに、ユーザーアクセス権限は作成した AWS IAM ロールによって制御されます。

料金と提供地域
開発者はこれらの新機能をすぐに活用できます。新機能と Amazon Cognito サービスを活用することの他の利点については開発者用リソースページを参照してください。ユーザープール内のグループを使用しても追加コストが発生しないというのは大きなニュースです。無料利用枠の後は、料金は、Monthly Active Users (MAU) に対してのみ発生します。また、Amazon Cognito では、ユーザーのアクセス権限を制御、また一意の識別子の生成のために Cognito フェデレーション識別機能を常時無料で使用できることを覚えておいてください。詳細については、Amazon Cognito 料金表ページを参照してください。

Tara

Amazon Cognito Your User Pools - 一般提供を開始

数か月前公開したブログ Amazon Cognito の新しい Your User Pools 機能についてご紹介しました。その時点では、ユーザーのモバイルアプリやウェブアプリでサインアップやサインインに同機能を使用することをご説明しました。完全マネージド型のユーザーディレクトリでは、ユーザー数億人の拡大を可能にしたり、各 AWS アカウントで複数のディレクトリを使用することができます。ユーザープールは数分で作成でき、新規ユーザーがお客様のアプリまたはサービスにサインアップする時に、どの属性 (アドレス、メール、性別、電話番号やカスタム属性など) に入力の必要があるか指定することができます。セキュリティの面では、お好みに合わせたパスワード強度を特定したり、Multi-Factor Authentication (MFA) の使用の強制やユーザーの電話番号またはメールアドレスでの確認を求めることができます。

一般提供を開始
Your User Pools のパブリックベータ版を開始したところ、数多くの素晴らしいフィードバックをいただきました。そして本日、Your User Pools の一般公開を開始した他、このリリースに伴い、いくつかの新機能も追加しました。

  • Device Remembering – Cognito は各ユーザーがどのデバイスからサインインしたか記憶することができます。
  • User Search – 属性に基づきユーザープールでユーザーを検索できます。
  • Customizable Email Addresses – ユーザープール内でユーザーのメールアドレスを管理できます。
  • Attribute Permissions – 各ユーザーの属性を細かく設定することができます。
  • Custom Authentication Flow – 新たな API や Lambda トリガーを使用してサインインフローをカスタマイズできます。
  • Admin Sign-in – バックエンドサーバーや Lambda 関数からユーザーをアプリにサインインさせることができます。
  • Global Sign-out – サインインしているすべてのデバイスやブラウザからユーザーがサインアウトできるようにします。
  • Custom Expiration Period – トークン更新に有効期間を設定できます。
  • API Gateway Integration – ユーザープールを使用して Amazon API Gateway リクエストを承認できます。
  • New Regions – 追加した AWS リージョンでも Cognito Your User Pools をご利用いただけます。

次に各新機能の詳細についてご説明します。

Device Remembering
Cognito で各ユーザーがサインインに使用したデバイス一連を記録できるようになりました。ユーザープールの作成者には、この操作のリクエストをユーザーに許可するオプションがあります。ユーザープールで MFA を有効にしている場合は、記録されたデバイスで MFA コード入力の必要を取り消すこともできます。これにより、認識されていないデバイスには MFA コードの入力を要求し、記録されたデバイスのログインプロセスを簡素化かつ合理化することが可能になりました。また、ユーザーのデバイスをリストにし、リモートからデバイスよりサインアウトできるようにします。ユーザープールの作成時に、この機能を有効にしたりカスタマイズすることができます。新しいユーザープールの作成時に同機能を有効にし、カスタマイズする方法については次をご覧ください。まず、[Always] または [User Opt-in] をクリックして同機能を有効にします。

次に、記憶したデバイスで MFA を非表示にするか決定します。

AWS Mobile SDK for iOS、Android、JavaScript には、デバイスを記憶するためにアプリから呼び出すことができる新な方法が備わっています。

User Search
Your User Pool の作成者は、次のような属性に基づきユーザーを検索することができます。 username, given_name, family_name, name, preferred_user_name, email, phone_number, status または user_status.

完全一致またはプレフィックス一致を行うには AWS Management Console ListUsers API 関数または list-users コマンドラインツールを使用します。コンソールで検索する場合

Customizable Email Addresses
ユーザーとのコミュニケーションに使用するメールアドレスの差出人や返信先を特定することができます。新しいプールの作成時にアドレスを特定する場合

使用前に Amazon Simple Email Service (SES) で差出人のアドレスを確認する必要があります (詳しくは Verifying Email Addresses in Amazon SES をご覧ください)。

Attribute Permissions
各ユーザー属性で、アプリごとの読み取りや書き込み権限を設定することができます。これにより、どのアプリケーションがユーザー用に保管されているどの属性を閲覧したり変更できるか管理することが可能になります。例えばユーザーが潜在顧客であるか否かを示すように属性をカスタマイズすることができます。アプリがこの属性を見ることはできますが、直接変更することはできません。代わりに管理ツールまたはバックグラウンドプロセスを使用して属性を更新してください。Console、API、CLI でユーザー属性の権限を設定することができます。

Custom Authentication Flow
次の新しい API 関数をご利用いただけます (InitiateAuthRespondToAuthChallenge)。その他にも、3 つの新たな Lambda トリガーを使用して独自のサインインフローや既存のプロセスをカスタマイズすることができます。例えば経験レベルが異なるユーザー、ロケーション別、セキュリティ条件別などを対象に、ユーザーフローをカスタマイズすることができます。必要に応じて特定のユーザーまたはユーザー全員に CAPTCHA の使用を要求することもできます。Lambda トリガーの種類

Define Auth Challenge – カスタム認証フローの開始を呼び出します。Create Auth Challenge – カスタム認証チャレンジが規定された場合に呼び出されます。Verify Auth Challenge Response – カスタム認証チャレンジの有効性を確認する場合に呼び出されます。次のように Console からトリガーを設定することができます。

Global Sign-out
ログイン済みのデバイスすべてからサインアウトするオプションをユーザーに提供できるようになりました。有効、期限切れではなく、呼び出されていないアクセストークンを使用して [GlobalSignOut] 関数を呼び出すことができます。開発者は Pool ID と username を使用して [AdminUserGlobalSignOut] 関数を呼び出し、どのユーザーもリモートからサインアウトさせることができます。

Custom Expiration Period
Cognito サインインは、「更新」トークンを使用してアプリケーションを開くたびにサインインする必要を省きます。デフォルトでトークンは 30 日が経過すると無効になります。セキュリティと利便性のバランスをほどよく維持するため、各ユーザープールが生成する更新トークンの有効期間をカスタマイズ設定できるようになりました。

API Gateway Integration
API リクエストを認証するため、Cognito ユーザープールが Amazon API Gateway と密接に連携して対処できるようになりました。ID トークンを受け入れるように API Gateway を設定し、ユーザープールにおけるユーザー状況を認証できます。その場合は、まずユーザープールを参考にしてアイデンティティトークンを含むリクエストヘッダーをを選び、Cognito User Pool Authorizer を作成します。

希望する方法にアクセスし新しい認証を選択します。

New Regions
今回のリリースに伴い、US West (Oregon) リージョンでも Cognito をご利用いただけるようになりました。すでにご利用可能な US East (Northern Virginia) リージョンの他に Europe (Ireland)、US West (Oregon)、 Asia Pacific (Tokyo) リージョンでも Your User Pools をお使いいただけます。

今すぐ利用可能
今すぐ新機能をご利用いただけます。詳細は Getting Started with Your User Pools in Amazon Cognito をご覧ください。

Jeff

[New] Amazon Cognito 向け User Pools

Amazon Cognito を使うことでバックエンドコードを書いたり、インフラストラクチャの管理をする必要なくモバイルや Web アプリに簡単に認証やユーザ管理とデータ同期を簡単に追加できます。ユーザごとの設定やアプリケーションの状態データをバックエンドコードを書いたり、インフラストラクチャの管理をする必要なく AWS Cloud に保存することが簡単になります。昨年、AWS CloudTrail サポートログインプロバイダとして Twitter および Digits の使用、Cognito におけるイベントに応答するAWS Lambda function の実行機能、そして Amazon Kinesis へのユーザアイデンティティデータのストリーミングといったいくつかのパワフルな新機能を Cognito に追加しました。

User Pools
モバイルと Web アプリに簡単にユーザサインアップとサインインを追加するのに Amazon Cognito を利用できるようになりました。User Pool の機能を用いて、数億ユーザまでスケールし、フルマネージドなので構築したり、セキュアにしたりアプリに対する認証をスケールしたりするのに関連する重労働について心配することなく独自のユーザディレクトリを作成できます。この機能は email による確認、電話番号による確認や多要素認証といった拡張されたセキュリティ機能も提供します。アプリ開発者として、みなさんはこういった目的のために、Federated Identity Pools と呼ぶようになった Cognito の機能を利用して、Amazon、Facebook、Google、Twitter もしくは Digits といった外部のアイデンティティプロバイダを利用するというオプションを既に持っていました。User Pool を使うことで Web とモバイルの SaaS アプリ、ゲームなどといった面でサインアップとサインインに詳細なコントロールが可能になります。あらゆるスケール(潜在的には数十や数億のユーザ)でディレクトリサービスを構築し稼働させることは簡単ではなく、ユーザ名、パスワード、email アドレスやその他のセンシティブな情報のかけらを管理するときに追加されるセキュリティの重荷とともに全くもって付加価値を生まない重労働です。User Pool を使う場合、独自のディレクトリサービスを構築し、稼働させる必要はありません。

アカウントごとの複数のUser Pool
自分の AWS アカウントに複数の User Pool を作成可能です(1プール内のアイデンティティは分離され他のプール内のものとも異なります)。各プールは名前が付けられ、各ユーザで保存したい属性(アドレス、email、電話番号、ロケールなど)に対するフルコントロールを持ちます。プールの作成後はユーザを認証し、クレデンシャルを取得するなどのために AWS Mobile SDK(iOS、AndroidとJavaScriptで利用可能)を使用できます。ユーザは SMS ベースの多要素認証(Multi-Factor Authentication、MFA)や電話や email によるアカウント確認を含む各種セキュリティ機能によりベネフィットを得ます。パスワード機能では通信上、クリアテキストなパスワードを送信しないようにSecure Remote Password (SRP)を利用します。

User Poolの作成
AWS Management Console (APIとCLIも利用可能です)から User Pool を作成するプロセスをウォークスルーしてみましょう。(仮想的な)私のアプリは PaymentApp と呼ばれますので PaymentAppUsers という名前のプールを作成します

デフォルトをレビューして受け入れるか全ての設定をすることもできます。ここでは後者のアクションを選択します。新規ユーザがサービスにサインアップする際に収集しなければいけない属性のセットを選択します。

カスタム属性をセットアップすることも可能です。私のアプリの場合、ユーザの使いたい支払い通貨を記録したいです。

それから望ましいパスワード強度を設定します。これはペイメントのアプリなので全ての選択肢をチェックします。

次に、多要素認証を有効にし、email アドレスと電話番号が確認される必要があることを示します。確認の各メソッドに関連するメッセージのカスタマイズも行います。

私のアプリはモバイルクライアントも持っているのでユニーク ID とシークレットキーを作成するようにします。

サインアップ、検証、認証そして確認のステップで Cognito に Lambda ファンクションを起動させるようにすることもできます(これはオプショナルですが、カスタム属性を確認ことによるサインアップワークフローをカスタマイズしたい場合にとても便利です)。

最後に、自身の選択をレビューしプールを作成します。

この時点でWebもしくはモバイルアプリのを開発する準備が整いました。

AsurionにおけるCognito

Asurion は2億以上の顧客にスマートフォンのような高付加価値なデバイス向けの保険契約を提供しています。Asurion は新たなデバイス保護アプリ向けのユーザディレクトリの管理のために Cognito を使う計画をしています。このアプリはデバイスに関するデータを収集し、利用料の最適化を目的としたリコメンドを行います。

Asurion は幅広いアイデンティティモデルのサポートを理由に Cognito を選択しています。アイデンティティシステムをスケールさせ、セキュアにするという重労働に対処する必要なく、彼らは自身のフルマネージドなディレクトリを保有したり、サードパーティのソーシャルアイデンティティプロバイダを通したユーザ認証を持つことができます。

Ravi Tiyyagura (Asurion’s Director of Enterprise Architecture) はこう言います。

数千万のエンドユーザに対するセキュアでシンプルなサインアップとサインイン体験を提供することはとても重要です。Amazon Cognito により、我々はバックエンドを構築し管理することに関して心配することなくそれをできます。

Ravi Tiyyagura (Asurion’s Director of Enterprise Architecture) はこう言います:

数千万のエンドユーザに対するセキュアでシンプルなサインアップとサインイン体験を提供することはとても重要です。Amazon Cognito により、我々はバックエンドを構築し管理することに関して心配することなくそれをできます。

Public Beta
We are launching user pools today as a public beta. All of the primary functionality is in place and you can use it to start building and testing your app. We expect to make it available for production use within a couple of months.

user pool を本日パブリックベータとしてローンチします。全ての主要な機能は整備されており、アプリの開発とテストを始めるために利用可能です。数ヶ月のうちにプロダクション用途で利用可能にするようにするつもりです。

— Jeff; (翻訳は西谷が担当しました。原文はこちら)