amafukuのブログ

雑多な記事を書いています。

<調整中>Amazon cognito(入門時に書いたメモを引用)

Powered by AWS Cloud Computing

今回は1年ほど前に初めてAWSを触ったときに作成した資料を

そのまま引用します。

間違っていることも多い可能性が高いので、あくまで個人用になるかも。。。

 

Googleドキュメントでメモしていたのでフォーマット調整に時間がかかるかもしれません。。。

要約

  • cognitoの認証はJWT(JSON Web Token)
  • JSONなのでそれをデコードすればどの言語でも対応可
  • cognitoの設定自体はそこまで難しくはない
  • ユーザー情報の検証はAPI Gatewayオーソライザーで行う
  • ユーザープールが今回はメインになりそう
  • IDプールはAWS内のサービスにサインインする機能
  • 実装時JWTの使用にはセキュリティに注意が必要
  • JSONでの認証なのでアクセスの権限も埋め込める
  • Amplifyを使用するとサインイン画面などが簡単に作られる


ユーザープール、IDプール、Cognito Sync、AWS AppSyncの
4つの機能で構成されたサービス。
ユーザープール作成ご、作成したユーザープールのトップ画面にて
プールIDが表示されるので、それを使用します。

最初の設定
・ユーザープールの作成

->ユーザープールの管理

プール名は任意

->デフォルトを確認する
サインインの設定
    ユーザーのログイン時に使用する要素を選択
        ユーザー名
        メールアドレス
        電話番号
        任意のユーザー名
        一つだけではなく複数を選択しユーザーが選んで使うことも可能
        作成後は変更ができないので注意

        標準属性の選択は
        ユーザー作成の際に求める情報を選択できる

        ここの設定によってサインアップの時に
   エラーが出てしまうことがあったため、
        ここについてより詳しく調べる
ここではなくIDプールの設定をしてそっちではじかれていた可能性が高そう

標準属性の使用はopenID Connectの仕様になっている

    カスタム属性の選択
        好きに作れる標準属性
サインイン時に
デバイスキー
名前
最後のIP
SDK
最後の利用日時
が機能を有効にすると保存される。

多要素認証(SMSやTOTP)は作成時に決めなければならない


->パスワードの設定
    パスワードの強度の設定
    普通に使う分には特殊記号の部分をチェックを外して使用することが多い

 

->ユーザー作成の許可
    管理者のみユーザー作成ができるのか、ユーザー自身でアカウントを作成できるかの選択。

->メール送信の設定
    AWS SESを使用してメールを送信するかcognitoで送信するか、
    送信メールの文章の編集などができる。

 

->アプリクライアント
    アプリケーションで使用する際にここで指定?
    ユーザープール作成後にこのアプリクライアントのIDが生成されるので、
    そのIDを使用。
 アプリケーションごとに機能や権限の設定が可能
 シークレットを割り当てたほうが良い
 シークレットはサーバーサイドで実装。(プライベートクライアント)
 ブラウザ上だとシークレットを割り当てられない(パブリッククライアント)
 ここのシークレットの話ももう少し調査しないとわからない部分がある


    「クライアントシークレットを生成」のチェックを外さないと、JavaScriptからAmazon Cognitoを使った認証をする際にうまくいかないようです。
    例外処理が行われるため。

    クライアントシークレットを生成: チェックを外す 
    サーバーベースの認証でサインイン API を有効にする (ADMIN_NO_SRP_AUTH): チェックを入れる

    ユーザープール作成後にユーザープール詳細からアプリクライアントの設定画面にいくと、
    そこでIDプロバイダの設定ができる。
    コールバックURLに
->デバイス記憶
    ログインした際のデバイスを記憶して同じデバイスからのログイン認証をスキップできる

 

トリガー
    Lambdaの情報が必要らしい。
ここで設定しておくとLambdaで作成したプログラムを
指定のアクションで動作させることができる?

->ユーザープール作成

 

・IDプールの作成

IDプール名の入力

未ログイン状態でのアプリの使用の許可をするか

認証フローの設定

認証プロバイダー
cognito使用の場合は
ユーザープールの
    プールID
    アプリクライアントID

googleなどのほかのアプリで認可できる?

IDプール作成

詳細を表示でロールの確認と編集が可能。
今回はそのまま許可
ここのロールはAWS IAMで設定可能

AWScognitoでの作業開始
プラットフォームの選択
    今回はJavascript
    ここで出てきたコードを使用して実装

・実装の際に必要になるJavascriptライブラリ
RSA and ECC in JavaScript
jsbn.js
jsbn2.js
    (余談:ECCとは楕円曲線暗号の略。RSA暗号の代わりとなり得る公開鍵暗号方式の一種
    RSA暗号とは、素因数分解の難しさを利用した暗号アルゴリズムのこと。)

Stanford Javascript Crypto Library
sjcl.js

AWS SDK for Javascript
aws-sdk.min.js

Amazon Cognito Identity SDK for Javascript
aws-cognito-sdk.min.js
amazon-cognito-identity.min.js


ユーザープールとIDプール

ユーザープール・・・認証サービス
    ID,パスワードなどの認証情報を保存してそれを活用、認証処理をする機能
    認証の後にCognitoトークンを使用して処理される。(トークンはJSON形式)
    ログインの機能。認証の処理対象がアプリ。
    WebやアプリケーションにIdentity Providerを通じて連携

    ユーザープールのすべてのユーザーはSDKを通じてアクセスできるディレクトリプロファイルがある。

        ・サインアップ、サインインの機能
        ・サインインのカスタマイズ
        ・ユーザーディレクトリと、ユーザープロファイルの管理
        ・カスタマイズされたワークフローとLambdaトリガーによるユーザー移行

IDプール・・・認可サービス
    権限の機能のようなもので、ログイン後のユーザーがどのサービスの利用権利があるかを処理。
    処理対象がAWSのサービス。 ー基本的には上記はセットで実装するー
追記
ユーザープールとIDプールはセットで使用しなくても
API Gatewayのオーソライザーを作成してユーザープールの設定をして使うこともできる。
IDプールとセットでやっている時は画面読み込み時にリージョンとアイデンティティプールIDをセットしているだけのように見える。。。
実際にその処理が必要なのかは別途調査。


Cognito Sync・・・公式から推奨されていないもの。
    モバイルアプリとクラウド間でのデータ同期機能。

Cognito AppSync・・・Cognito Syncの高機能版で公式推奨機能。
    GraphQLというクエリ言語が利用可能。

        GraphQL・・・アプリ、プログラミング、インターフェース向けのクエリ言語とサーバーサイドランタイムの両方の事。
                APIの速度、柔軟性、使いやすさを向上させるために設計された。


提携している企業が提供するクラウド認証サービス
Auth0
onelogin
    シングルサインオンのサービス。
    AWSで不足する機能を補える


cognitoはOAuth2.0が認可に使用されている。
使える認可方法
Authorization code grant
Implicit grant
Client credentials

スコープ(どのリソースを扱うか)
openIDの場合はidのidpでのユーザーIDが取得可能


IDプロバイダー(idp・・・アイデンティティ・プロバイダ)
ユーザーのデジタルIDを保存、管理する
フェデレーション、分散ネットワーク内の依存アプリケーションに認証サービスを提供するシステムエンティティ。
ユーザー認証サービスの様な感じ?

フェデレーション
一度認証を通るとその情報を使用し、認可のあるシステムを使用可能にする仕組み


IAMロール
AWSのサービスや他のアカウントに対してAWSの操作権限を付与するための仕組み。
今回は関係ない?


AWS Amplifyと組み合わせると開発が楽になるとのこと。
Amplifyとは・・・ウェブアプリやモバイルアプリ開発に使えるフレームワーク、ホスティングサービス。
FireBaseのような感じ?今回は使えなさそう。。。?


Javascriptを使ったログイン機能の実装、
Laravelでの記事もあり。https://qiita.com/ayasamind/items/9b07c8c2fd433505a0eb

ユーザープールとIDプールを作成後サインアップ、サインイン画面の作成記事
https://hacknote.jp/archives/57871/


やっている設定内容は今回とは関係はなさそうですが、念のため記載
https://fintan.jp/?p=5593

AWS Amplify + Angular6 + cognitoでログインページの制作ページ(bootstrapも使用)
https://dev.classmethod.jp/articles/aws-amplify-angular6-cognito-loginpage-backend/

cognitoとフェデレーションについて
https://qiita.com/poruruba/items/6ea55dd2befb92df6628

 

 

 

 

 

 

 

 

 

 

外部リソースへのアクセス

認証成功後、cognitoから各自サーバーのリソースへのアクセス、
API Gatewayへのアクセスを制御することができるようになる。

外部に飛ばす情報はユーザープールトークン。


・アクセストークン
主にユーザープールのユーザー属性の追加・変更・削除の際に使用。
規格はJWT(JSON Web Token)
・IDトークン
主に認証時に使用。
API Gatewayとのやり取りもこのトークン
規格はJWT(JSON Web Token)
認証されたユーザーの情報(クレーム)が含まれているので
それをアプリ側で使用可能。
・リフレッシュトークン
IDトークン、アクセストークンの更新に使用するトークン

の3種類がある。

cognitoのサインアウトの扱い
サインアウト=トークンの無効化
IDトークン以外を無効にしてサインアウト状態にする。

 

アクセストークンの有効期限は
ユーザープールの設定から、アプリクライアントの項目内で設定可能。

 

トークンの情報はJSON形式

Javascriptでの実装が素直?

AWS API Gatewayのオーソライザーを使用してHTTP APIへのアクセス
openID Connect、OAuth2.0フレームワークの一部として
APIへのクライアントアクセスを制限できる。


APIリクエストの承認
identitySourceでトークン確認
トークンのみか、ベアラーのプレフィックスがついたトークンを含めることが可能
ベアラー(運送者、伝達者。信号やビット列をそのまま送信するサービス)
プレフィックス(接頭辞)
伝達者の情報をトークンのヘッダーにくっつけること?
openID
IDトークンを発行する為の仕様。
以下の説明はIDトークンの一種の説明。

JWS(JSON Web Signature)
3つのエリアに分けられ、
ヘッダー
ペイロード(本文)
署名
を表している。

元のデータをbase64urlでエンコードしている。
ヘッダー部のデコード
"kid","alg"というパラメーターが含まれている。
パラメーターは他にもいくつかある。
algは署名のアルゴリズムを表している

JWE(JSON Web Encryption)
ヘッダー
キー
初期ベクター
暗号文
認証タグ

上記5つのフィールドを持つ形式。
IDトークンを暗号化したいときに利用される形式。


JWT(JSON Web Token)
JSON形式のクレームの集合をJWSやJWEに埋め込んだもの

クレーム・・・請求、要求、断言

JWS形式のJWT
base64urlエンコードをした後にペイロード(本文)に埋め込み

JWE形式のJWT
暗号化をしてからbase64urlエンコードをし、暗号文に埋め込み

Nested JWT
JWSの中にJWEを入れたり、JWEの中にJWSを入れた形式のJWT(ネスト)

クレームについて
JSONオブジェクト内のキーとバリューのセットで表す。

 


ここを読ませていただきました。
https://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06

 

openIDの実装方法
cognitoの設定は
IAMから設定

https://dev.classmethod.jp/articles/cognito-userpool-openid-connect-line/

上記URLはcognitoとopenIDでLineアカウント連携の記事

IDフェデレーション
独自のID管理システムを持つ複数のセキュリティドメイン間で
それぞれのユーザーIDをリンクさせる役割。
一つのドメインで認証を受けたユーザーはほかのドメインでもログインなしでアクセス可能。

AWS Lambda
サーバーレスでプログラムを実行可能。

https://qiita.com/poruruba/items/042adba2ac9a34839546

 

JWT改ざん セキュリティ面での注意点

alg(アルゴリズム)
署名の項目を改ざんしてnoneを指定して検証を行わないことができてしまう
algに対してホワイトリストを作成して制限する対応
RS256のみ使用するなど

RS256
公開鍵方式
署名の作成に秘密鍵を利用し、検証に公開鍵を使用する。

 

 

 

 

 


JWT
クレーム(情報)の項目にユーザー権限を設定することで、
アクセス制限をかけることもできる。

・安全性
署名が含まれているので改ざんをチェックできる。

・実装
Tokenの発行が容易
・管理
URLに含めることができる文字列なのでHTTPリクエストでの取り扱い〇
認証情報がJWTに入れてあるため
認証j方法をサーバーで管理する必要がない


ユーザー登録
・フロントでユーザー情報の入力

・入力情報の送信


・サーバーでリクエストデータでJWTの生成

・トークンをフロントへ返す


・フロントでトークンを受け取る

・トークンがbase64urlで返ってくるのでbase64に変換

・base64のトークンをローカルストレージに保存


登録後のログイン

・トークンの有無

・ローカルストレージのトークンを確認
HTTPヘッダにトークンを入れてサーバーへ

・トークンの有効期限の確認
期限切れの場合はサーバーへ更新のリクエスト


・トークン更新の場合はサーバーからJWTを更新して返却
返却されたものはローカルストレージに保存


・サーバーにアクセス。

 

 

 


cognitoのフェデレーション
Cogntioフェデレーテッドアイデンティティ
IDプールのことらしい

Cognitoユーザーサードパーティ(フェデレーション)
IDプール経由のフェデレーションと別のもの。

利用できるAPI


Cognito Identity Provider API
サインインのユーザーインターフェイスを自身で用意し
Cognitoのアプリケーションを呼び出す。
各種操作に対応したユーザープール独自のAPIが使用できる。
ユーザーが入力した内容をAPIに送信し、各種操作を行う。

管理者用のAPI・・・AdminAPI
IAMロールを利用して認証
管理者としてサーバー側から呼び出す前提
非管理者のAPI・・・API
アプリクライアントID(+シークレット)で認証
ユーザーとしてサーバー側、クライアント側から呼び出せる
Cognito Auth APIとHosted UI
Hosted UIをという画面を使用。
そこからCognitoのアプリケーションを呼び出して自身のアプリケーションへ


サインインは認証フローを指定しAPIを呼び出す。
主に5種類あり、アプリクライアントによって許可されている認証フローを使用。

Cognito Identity ProviderAPI
認証フローの種類
USER_SRP_AUTH・・・標準的なフロー安全な方法。チャレンジレスポンス
CUSTOM_AUTH・・・Lambdaファンクションでやり取りの内容をカスタマイズ使用
USER_PASSWORD_AUTH・・・パスワードそのものでの認証
ADMIN_USER_PASSWORD_AUTH・・・上記と同じだがAdmin専用サーバーからのみ
REFRESH_TOKEN_AUTH・・・更新トークンから新しいトークンを取得


Hosted UI
ユーザー入力のフォームの作成の必要はないが、その分カスタマイズができず、
日本語の入力画面が作れない。(今回は必要なさそう)

 

今回使用するAPIは
Cognito Identity Provider APIとCognito Auth APIの両方を使用するか
Cognito Identity Providerのみで使うかになるかと思います。

Cognito Auth API を使用する場面は、外部IDプロバイダを使用するかどうか

API呼び出し実装時はSDKやLibraryを使用する。
SDKの種類
AWS SDK foe Javascript
Amazon Cognito Identity SDK for Javascript
AWS Mobile SDK
AWS Amplify Library

Amplifyを使うと、日本語対応していてログイン画面のUIを使用可能

 

API Gateway
・Lambda、EC2、AWS以外で公開されてるアプリケーションをAPIとして公開する機能

・APIの管理、運用をAWS側で提供するサービス

AWS amplify
認証画面を簡単に作成できる
日本語化するためにコードをいじる必要性あり。

日本語化について
https://qiita.com/Akio-1978/items/213a352dbc98578d83aa

 

AWS内のサービスで
Cognito + Amplify

https://qiita.com/yoskeoka/items/7474845087c66cf91b27

JWTの認証について
https://remix-yh.net/1689/


OAuth実装について
https://tech-lab.sios.jp/archives/8091


cognitoユーザープール
ユーザー削除について
ユーザープールを開いて「ユーザーとグループ」
消したいユーザー名を選択
「ユーザーを無効化」→「ユーザー削除」が出現
それを押すとユーザー削除


新規登録時の認証コード及びURLの有効期限
24時間で変更不可

パスワード忘れた時の認証コード及びURLの有効期限
1時間で変更不可