デベロッパーが認証したアイデンティティ (ID プール) - Amazon Cognito

デベロッパーが認証したアイデンティティ (ID プール)

Amazon Cognito は、Facebook (ID プール)Google (ID プール)Login with Amazon (ID プール)、および 「Apple でサインイン」 (ID プール) 経由でのウェブ ID フェデレーションに加えて、デベロッパーが認証したアイデンティティもサポートします。デベロッパーが認証したアイデンティティでは、ユーザーデータの同期化と AWS リソースへのアクセスに引き続き Amazon Cognito を使用しながら、独自の既存認証プロセス経由でユーザーを登録し、認証することができます。デベロッパーが認証したアイデンティティの使用には、エンドユーザーのデバイス、認証のバックエンド、および Amazon Cognito 間の対話が関連します。詳細については、AWS のブログを参照してください。

認証のフローについて

デベロッパーが認証したアイデンティティの認証フローの詳細と、外部プロバイダーの認証フローの違いについては、「ID プール (フェデレーティッドアイデンティティ) の認証フロー」を参照してください。

デベロッパー名を指定して ID プールに関連付ける

デベロッパーが認証したアイデンティティを使用するには、デベロッパープロバイダーに関連付けられた ID プールが必要です。そのためには、以下の手順を実行します。

  1. Amazon Cognito コンソールにログインします。

  2. 新しい ID プールを作成し、プロセスの一環として [Authentication Providers] (認証プロバイダー) の [Custom] (カスタム) タブでデベロッパープロバイダー名を定義します。

  3. または、既存の ID プールを編集し、[Authentication Providers] の [Custom] タブでデベロッパー名を指定します。

注意: プロバイダー名を設定した場合、それを変更することはできません。

Amazon Cognito コンソールでの作業に関する追加の手順については、「Amazon Cognito コンソールの使用」を参照してください。

ID プロバイダーの実装

Android

デベロッパーが認証したアイデンティティを使用するには、AWSAbstractCognitoIdentityProvider を拡張する独自の ID プロバイダークラスを実装します。ID プロバイダークラスは、属性としてトークンを含むレスポンスオブジェクトを返す必要があります。

以下に示しているのは、ID プロバイダーのシンプルな例です。

public class DeveloperAuthenticationProvider extends AWSAbstractCognitoDeveloperIdentityProvider { private static final String developerProvider = "<Developer_provider_name>"; public DeveloperAuthenticationProvider(String accountId, String identityPoolId, Regions region) { super(accountId, identityPoolId, region); // Initialize any other objects needed here. } // Return the developer provider name which you choose while setting up the // identity pool in the &COG; Console @Override public String getProviderName() { return developerProvider; } // Use the refresh method to communicate with your backend to get an // identityId and token. @Override public String refresh() { // Override the existing token setToken(null); // Get the identityId and token by making a call to your backend // (Call to your backend) // Call the update method with updated identityId and token to make sure // these are ready to be used from Credentials Provider. update(identityId, token); return token; } // If the app has a valid identityId return it, otherwise get a valid // identityId from your backend. @Override public String getIdentityId() { // Load the identityId from the cache identityId = cachedIdentityId; if (identityId == null) { // Call to your backend } else { return identityId; } } }

この ID プロバイダーを使用するには、これを CognitoCachingCredentialsProvider に渡す必要があります。例を示します。

DeveloperAuthenticationProvider developerProvider = new DeveloperAuthenticationProvider( null, "IDENTITYPOOLID", context, Regions.USEAST1); CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider( context, developerProvider, Regions.USEAST1);

iOS - Objective-C

デベロッパーが認証したアイデンティティを使用するには、AWSCognitoCredentialsProviderHelper を拡張する独自の ID プロバイダークラスを実装します。ID プロバイダークラスは、属性としてトークンを含むレスポンスオブジェクトを返す必要があります。

@implementation DeveloperAuthenticatedIdentityProvider /* * Use the token method to communicate with your backend to get an * identityId and token. */ - (AWSTask <NSString*> *) token { //Write code to call your backend: //Pass username/password to backend or some sort of token to authenticate user //If successful, from backend call getOpenIdTokenForDeveloperIdentity with logins map //containing "your.provider.name":"enduser.username" //Return the identity id and token to client //You can use AWSTaskCompletionSource to do this asynchronously // Set the identity id and return the token self.identityId = response.identityId; return [AWSTask taskWithResult:response.token]; } @end

この ID プロバイダーを使用するには、次の例に示すように、それを AWSCognitoCredentialsProvider に渡します。

DeveloperAuthenticatedIdentityProvider * devAuth = [[DeveloperAuthenticatedIdentityProvider alloc] initWithRegionType:AWSRegionYOUR_IDENTITY_POOL_REGION identityPoolId:@"YOUR_IDENTITY_POOL_ID" useEnhancedFlow:YES identityProviderManager:nil]; AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:AWSRegionYOUR_IDENTITY_POOL_REGION identityProvider:devAuth];

認証されていないアイデンティティとデベロッパーが認証したアイデンティティの両方をサポートする場合は、logins の実装で AWSCognitoCredentialsProviderHelper メソッドをオーバーライドします。

- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins { if(/*logic to determine if user is unauthenticated*/) { return [AWSTask taskWithResult:nil]; }else{ return [super logins]; } }

デベロッパーが認証したアイデンティティとソーシャルプロバイダーをサポートする場合は、loginsAWSCognitoCredentialsProviderHelper 実装で現在のプロバイダーが誰であるかを管理する必要があります。

- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins { if(/*logic to determine if user is unauthenticated*/) { return [AWSTask taskWithResult:nil]; }else if (/*logic to determine if user is Facebook*/){ return [AWSTask taskWithResult: @{ AWSIdentityProviderFacebook : [FBSDKAccessToken currentAccessToken] }]; }else { return [super logins]; } }

iOS - Swift

デベロッパーが認証したアイデンティティを使用するには、AWSCognitoCredentialsProviderHelper を拡張する独自の ID プロバイダークラスを実装します。ID プロバイダークラスは、属性としてトークンを含むレスポンスオブジェクトを返す必要があります。

import AWSCore /* * Use the token method to communicate with your backend to get an * identityId and token. */ class DeveloperAuthenticatedIdentityProvider : AWSCognitoCredentialsProviderHelper { override func token() -> AWSTask<NSString> { //Write code to call your backend: //pass username/password to backend or some sort of token to authenticate user, if successful, //from backend call getOpenIdTokenForDeveloperIdentity with logins map containing "your.provider.name":"enduser.username" //return the identity id and token to client //You can use AWSTaskCompletionSource to do this asynchronously // Set the identity id and return the token self.identityId = resultFromAbove.identityId return AWSTask(result: resultFromAbove.token) }

この ID プロバイダーを使用するには、次の例に示すように、それを AWSCognitoCredentialsProvider に渡します。

let devAuth = DeveloperAuthenticatedIdentityProvider(regionType: .YOUR_IDENTITY_POOL_REGION, identityPoolId: "YOUR_IDENTITY_POOL_ID", useEnhancedFlow: true, identityProviderManager:nil) let credentialsProvider = AWSCognitoCredentialsProvider(regionType: .YOUR_IDENTITY_POOL_REGION, identityProvider:devAuth) let configuration = AWSServiceConfiguration(region: .YOUR_IDENTITY_POOL_REGION, credentialsProvider:credentialsProvider) AWSServiceManager.default().defaultServiceConfiguration = configuration

認証されていないアイデンティティとデベロッパーが認証したアイデンティティの両方をサポートする場合は、logins の実装で AWSCognitoCredentialsProviderHelper メソッドをオーバーライドします。

override func logins () -> AWSTask<NSDictionary> { if(/*logic to determine if user is unauthenticated*/) { return AWSTask(result:nil) }else { return super.logins() } }

デベロッパーが認証したアイデンティティとソーシャルプロバイダーをサポートする場合は、loginsAWSCognitoCredentialsProviderHelper 実装で現在のプロバイダーが誰であるかを管理する必要があります。

override func logins () -> AWSTask<NSDictionary> { if(/*logic to determine if user is unauthenticated*/) { return AWSTask(result:nil) }else if (/*logic to determine if user is Facebook*/){ if let token = AccessToken.current?.authenticationToken { return AWSTask(result: [AWSIdentityProviderFacebook:token]) } return AWSTask(error:NSError(domain: "Facebook Login", code: -1 , userInfo: ["Facebook" : "No current Facebook access token"])) }else { return super.logins() } }

JavaScript

バックエンドからアイデンティティ ID とセッショントークンを取得したら、それらを AWS.CognitoIdentityCredentials プロバイダーに渡します。例を示します。

AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: 'IDENTITY_POOL_ID', IdentityId: 'IDENTITY_ID_RETURNED_FROM_YOUR_PROVIDER', Logins: { 'cognito-identity.amazonaws.com': 'TOKEN_RETURNED_FROM_YOUR_PROVIDER' } });

Unity

デベロッパーが認証したアイデンティティを使用するには、CognitoAWSCredentials を拡張し、RefreshIdentity メソッドを上書きして、ユーザー ID とトークンをバックエンドから取得して返す必要があります。「example.com」という仮定のバックグランドに接続する ID プロバイダーの簡単な例を以下に示します。

using UnityEngine; using System.Collections; using Amazon.CognitoIdentity; using System.Collections.Generic; using ThirdParty.Json.LitJson; using System; using System.Threading; public class DeveloperAuthenticatedCredentials : CognitoAWSCredentials { const string PROVIDER_NAME = "example.com"; const string IDENTITY_POOL = "IDENTITY_POOL_ID"; static readonly RegionEndpoint REGION = RegionEndpoint.USEast1; private string login = null; public DeveloperAuthenticatedCredentials(string loginAlias) : base(IDENTITY_POOL, REGION) { login = loginAlias; } protected override IdentityState RefreshIdentity() { IdentityState state = null; ManualResetEvent waitLock = new ManualResetEvent(false); MainThreadDispatcher.ExecuteCoroutineOnMainThread(ContactProvider((s) => { state = s; waitLock.Set(); })); waitLock.WaitOne(); return state; } IEnumerator ContactProvider(Action<IdentityState> callback) { WWW www = new WWW("http://example.com/?username="+login); yield return www; string response = www.text; JsonData json = JsonMapper.ToObject(response); //The backend has to send us back an Identity and a OpenID token string identityId = json["IdentityId"].ToString(); string token = json["Token"].ToString(); IdentityState state = new IdentityState(identityId, PROVIDER_NAME, token, false); callback(state); } }

上記のコードでは、スレッドディスパッチャーオブジェクトを使用してコルーチンを呼び出します。プロジェクトでこれを行う方法がない場合は、シーンで以下のスクリプトを使用できます。

using System; using UnityEngine; using System.Collections; using System.Collections.Generic; public class MainThreadDispatcher : MonoBehaviour { static Queue<IEnumerator> _coroutineQueue = new Queue<IEnumerator>(); static object _lock = new object(); public void Update() { while (_coroutineQueue.Count > 0) { StartCoroutine(_coroutineQueue.Dequeue()); } } public static void ExecuteCoroutineOnMainThread(IEnumerator coroutine) { lock (_lock) { _coroutineQueue.Enqueue(coroutine); } } }

Xamarin

デベロッパーが認証したアイデンティティを使用するには、CognitoAWSCredentials を拡張し、RefreshIdentity メソッドを上書きして、ユーザー ID とトークンをバックエンドから取得して返す必要があります。「example.com」という仮定のバックグランドに接続する ID プロバイダーの簡単な例を以下に示します。

public class DeveloperAuthenticatedCredentials : CognitoAWSCredentials { const string PROVIDER_NAME = "example.com"; const string IDENTITY_POOL = "IDENTITY_POOL_ID"; static readonly RegionEndpoint REGION = RegionEndpoint.USEast1; private string login = null; public DeveloperAuthenticatedCredentials(string loginAlias) : base(IDENTITY_POOL, REGION) { login = loginAlias; } protected override async Task<IdentityState> RefreshIdentityAsync() { IdentityState state = null; //get your identity and set the state return state; } }

ログインマップの更新 (Android および iOS のみ)

Android

ご使用の認証システムでユーザーが正常に認証されたら、デベロッパープロバイダー名と開発ユーザー ID (認証システムでユーザーを一意に識別する英数字の文字列) を使用してログインマップを更新します。refresh が変更されている可能性があるため、ログインマップを更新した後は、必ず identityId メソッドを呼び出してください。

HashMap<String, String> loginsMap = new HashMap<String, String>(); loginsMap.put(developerAuthenticationProvider.getProviderName(), developerUserIdentifier); credentialsProvider.setLogins(loginsMap); credentialsProvider.refresh();

iOS - Objective-C

認証情報がないか、または期限切れ場合、iOS SDK は logins メソッドを呼び出して最新のログインマップを取得するのみです。SDK で新しい認証情報の入手を強制する場合は (たとえば、エンドユーザーが認証されていない状態から認証され、認証されたユーザーに対して認証情報を必要とするなど)、clearCredentialscredentialsProvider を呼び出します。

[credentialsProvider clearCredentials];

iOS - Swift

認証情報がないか、または期限切れ場合、iOS SDK は logins メソッドを呼び出して最新のログインマップを取得するのみです。SDK で新しい認証情報の入手を強制する場合は (たとえば、エンドユーザーが認証されていない状態から認証され、認証されたユーザーに対して認証情報を必要とするなど)、clearCredentialscredentialsProvider を呼び出します。

credentialsProvider.clearCredentials()

トークンの取得 (サーバー)

GetOpenIdTokenForDeveloperIdentity を呼び出してトークンを取得します。この API は、AWS デベロッパーの認証情報を使用してバックエンドから呼び出す必要があります。クライアント SDK から呼び出すことはできません。API は Cognito ID プール ID (ID プロバイダー名をキーとして、識別子を値として含むログインマップ) と、オプションで Cognito アイデンティティ ID (認証されていないユーザーを認証する場合など) を受け取ります。識別子はユーザーのユーザー名、メールアドレス、または数値の場合があります。API は、ユーザーの一意の Cognito ID と、エンドユーザーの OpenID Connect トークンを使用して呼び出しに応答します。

GetOpenIdTokenForDeveloperIdentity によって返されるトークンについては、以下の点に注意してください。

  • トークンのカスタムの有効期限を指定して、トークンをキャッシュすることができます。カスタムの有効期限を指定しない場合、トークンは 15 分間有効です。

  • 設定できる最大のトークンの期間は 24 時間です。

  • トークンの期間を増やすことによるセキュリティへの影響について注意してください。攻撃者がこのトークンを取得した場合、トークンの期間を通じてそれをエンドユーザーの AWS 認証情報と交換することができます。

以下の Java スニペットは、Amazon Cognito クライアントを初期化して、デベロッパーが認証したアイデンティティのトークンを取得する方法を示しています。

// authenticate your end user as appropriate // .... // if authenticated, initialize a cognito client with your AWS developer credentials AmazonCognitoIdentity identityClient = new AmazonCognitoIdentityClient( new BasicAWSCredentials("access_key_id", "secret_access_key") ); // create a new request to retrieve the token for your end user GetOpenIdTokenForDeveloperIdentityRequest request = new GetOpenIdTokenForDeveloperIdentityRequest(); request.setIdentityPoolId("YOUR_COGNITO_IDENTITY_POOL_ID"); request.setIdentityId("YOUR_COGNITO_IDENTITY_ID"); //optional, set this if your client has an //identity ID that you want to link to this //developer account // set up your logins map with the username of your end user HashMap<String,String> logins = new HashMap<>(); logins.put("YOUR_IDENTITY_PROVIDER_NAME","YOUR_END_USER_IDENTIFIER"); request.setLogins(logins); // optionally set token duration (in seconds) request.setTokenDuration(60 * 15l); GetOpenIdTokenForDeveloperIdentityResult response = identityClient.getOpenIdTokenForDeveloperIdentity(request); // obtain identity id and token to return to your client String identityId = response.getIdentityId(); String token = response.getToken(); //code to return identity id and token to client //...

上記の手順に従って、アプリでデベロッパーが認証したアイデンティティを統合できます。問題またはご質問がある場合は、お気軽にフォーラムに投稿してください。

既存のソーシャル ID への接続

デベロッパーが認証したアイデンティティを使用する際のプロバイダーのすべてのリンク作成は、バックエンドから行う必要があります。ユーザーのソーシャル ID (Login with Amazon、「Apple でサインイン」、Facebook、または Google) にカスタム ID を接続するには、GetOpenIdTokenForDeveloperIdentity を呼び出すときに、ログインマップに ID プロバイダーのトークンを追加します。これを可能にするため、クライアント SDK からバックエンドを呼び出してエンドユーザーを認証するときは、エンドユーザーのソーシャルプロバイダートークンを追加で渡します。

たとえば、カスタム ID の Facebook へのリンクを試みている場合、GetOpenIdTokenForDeveloperIdentity を呼び出すときに、ID プロバイダー ID に加えて Facebook のトークンをログインマップに追加します。

logins.put("YOUR_IDENTITY_PROVIDER_NAME","YOUR_END_USER_IDENTIFIER"); logins.put("graph.facebook.com","END_USERS_FACEBOOK_ACCESSTOKEN");

プロバイダー間の移行のサポート

Android

アプリケーションでは、デベロッパーが認証したアイデンティティとともに、パブリックプロバイダー (Login with Amazon、「Apple でサインイン」、Facebook、または Google) を使用した、認証されていないアイデンティティまたは認証されたアイデンティティのサポートが必要になる場合があります。デベロッパーが認証したアイデンティティとその他のアイデンティティ (認証されていないアイデンティティと、パブリックプロバイダーを使用して認証されたアイデンティティ) の重要な違いは、identityId およびトークンの取得方法にあります。他のアイデンティティについては、モバイルアプリケーションが認証システムに接続する代わりに Amazon Cognito と直接やり取りします。そのため、モバイルアプリケーションは、アプリユーザーが行った選択に基づいて、2 つの明確の流れをサポートできる必要があります。そのためには、カスタム ID プロバイダーにいくつか変更を加える必要があります。

refresh メソッドでは、ログインマップを確認し、マップが空でなくデベロッパープロバイダー名を含むキーがある場合は、バックエンドを呼び出します。それ以外の場合は、getIdentityId メソッドを呼び出し、null を返します。

public String refresh() { setToken(null); // If the logins map is not empty make a call to your backend // to get the token and identityId if (getProviderName() != null && !this.loginsMap.isEmpty() && this.loginsMap.containsKey(getProviderName())) { /** * This is where you would call your backend **/ // now set the returned identity id and token in the provider update(identityId, token); return token; } else { // Call getIdentityId method and return null this.getIdentityId(); return null; } }

同様に、getIdentityId メソッドにも、ログインマップの内容に応じて 2 つのフローがあります。

public String getIdentityId() { // Load the identityId from the cache identityId = cachedIdentityId; if (identityId == null) { // If the logins map is not empty make a call to your backend // to get the token and identityId if (getProviderName() != null && !this.loginsMap.isEmpty() && this.loginsMap.containsKey(getProviderName())) { /** * This is where you would call your backend **/ // now set the returned identity id and token in the provider update(identityId, token); return token; } else { // Otherwise call &COG; using getIdentityId of super class return super.getIdentityId(); } } else { return identityId; } }

iOS - Objective-C

アプリケーションでは、デベロッパーが認証したアイデンティティとともに、パブリックプロバイダー (Login with Amazon、「Apple でサインイン」、Facebook、または Google) を使用した、認証されていない ID または認証されたアイデンティティのサポートが必要になる場合があります。これを行うには、AWSCognitoCredentialsProviderHelperlogins メソッドをオーバーライドし、現在の ID プロバイダーに基づいて正しいログインマップを返せるようにします。この例では、非認証、Facebook 認証、デベロッパー認証を切り替える方法を示しています。

- (AWSTask<NSDictionary<NSString *, NSString *> *> *)logins { if(/*logic to determine if user is unauthenticated*/) { return [AWSTask taskWithResult:nil]; }else if (/*logic to determine if user is Facebook*/){ return [AWSTask taskWithResult: @{ AWSIdentityProviderFacebook : [FBSDKAccessToken currentAccessToken] }]; }else { return [super logins]; } }

非認証から認証に移行するときは、[credentialsProvider clearCredentials]; を呼び出して、認証された新しい認証情報の取得を SDK に強制します。2 つの認証されたプロバイダーを切り替え、2 つのプロバイダーへのリンクを試みない (ログインディクショナリで複数のプロバイダー用のトークンを提供していない) 場合は、[credentialsProvider clearKeychain]; を呼び出します。これにより、認証情報とアイデンティティの両方がクリアされ、SDK は新しい認証を取得します。

iOS - Swift

アプリケーションでは、デベロッパーが認証したアイデンティティとともに、パブリックプロバイダー (Login with Amazon、「Apple でサインイン」、Facebook、または Google) を使用した、認証されていないアイデンティティまたは認証されたアイデンティティのサポートが必要になる場合があります。これを行うには、AWSCognitoCredentialsProviderHelperlogins メソッドをオーバーライドし、現在の ID プロバイダーに基づいて正しいログインマップを返せるようにします。この例では、非認証、Facebook 認証、デベロッパー認証を切り替える方法を示しています。

override func logins () -> AWSTask<NSDictionary> { if(/*logic to determine if user is unauthenticated*/) { return AWSTask(result:nil) }else if (/*logic to determine if user is Facebook*/){ if let token = AccessToken.current?.authenticationToken { return AWSTask(result: [AWSIdentityProviderFacebook:token]) } return AWSTask(error:NSError(domain: "Facebook Login", code: -1 , userInfo: ["Facebook" : "No current Facebook access token"])) }else { return super.logins() } }

非認証から認証に移行するときは、credentialsProvider.clearCredentials() を呼び出して、認証された新しい認証情報の取得を SDK に強制します。2 つの認証されたプロバイダーを切り替え、2 つのプロバイダーへのリンクを試みない (ログインディクショナリで複数のプロバイダー用のトークンを提供していない) 場合は、credentialsProvider.clearKeychain() を呼び出します。これにより、認証情報とアイデンティティの両方がクリアされ、SDK は新しい認証を取得します。

Unity

アプリケーションでは、デベロッパーが認証したアイデンティティとともに、パブリックプロバイダー (Login with Amazon、「Apple でサインイン」、Facebook、または Google) を使用した、認証されていないアイデンティティまたは認証されたアイデンティティのサポートが必要になる場合があります。デベロッパーが認証したアイデンティティとその他のアイデンティティ (認証されていないアイデンティティと、パブリックプロバイダーを使用して認証されたアイデンティティ) の重要な違いは、identityId およびトークンの取得方法にあります。他のアイデンティティについては、モバイルアプリケーションが認証システムに接続する代わりに Amazon Cognito と直接やり取りします。そのため、モバイルアプリケーションは、アプリユーザーが行った選択に基づいて、2 つの明確の流れをサポートできる必要があります。そのためには、カスタム ID プロバイダーにいくつか変更を加える必要があります。

Unity でこれを行うための推奨の方法は、AbstractCognitoIdentityProvider の代わりに AmazonCognitoEnhancedIdentityProvide から ID プロバイダーを拡張し、独自のメソッドの代わりに親 RefreshAsync メソッドを呼び出すことです (ユーザーが独自のバックエンドで認証されない場合)。ユーザーが認証されている場合、前に説明したのと同じ流れを使用できます。

Xamarin

アプリケーションでは、デベロッパーが認証したアイデンティティとともに、パブリックプロバイダー (Login with Amazon、「Apple でサインイン」、Facebook、または Google) を使用した、認証されていないアイデンティティまたは認証されたアイデンティティのサポートが必要になる場合があります。デベロッパーが認証したアイデンティティとその他のアイデンティティ (認証されていないアイデンティティと、パブリックプロバイダーを使用して認証されたアイデンティティ) の重要な違いは、identityId およびトークンの取得方法にあります。他のアイデンティティについては、モバイルアプリケーションが認証システムに接続する代わりに Amazon Cognito と直接やり取りします。そのため、モバイルアプリケーションは、アプリユーザーが行った選択に基づいて、2 つの明確の流れをサポートできる必要があります。そのためには、カスタム ID プロバイダーにいくつか変更を加える必要があります。