開發人員驗證的身分 - Amazon Cognito

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

開發人員驗證的身分

除了透過 將 Facebook 設定為身分集區 IdP將 Google 設定為身分集區 IdP將 Amazon 登入設定為身分集區 IdP設定使用 Apple 登入作為身分集區 IdP 的 Web 聯合身分,Amazon Cognito 還支援開發人員驗證的身分。透過開發人員驗證身分,您可以透過現有的身分驗證程序註冊和驗證使用者,同時仍使用 Amazon Cognito 同步使用者資料和存取 AWS 資源。使用開發人員驗證的身分時,需要最終使用者裝置、身分驗證後端與 Amazon Cognito 之間的互動。如需詳細資訊,請參閱 AWS 部落格中的了解 Amazon Cognito 身分驗證第 2 部分:開發人員驗證身分

了解身分驗證流程

GetOpenIdTokenForDeveloperIdentity API 此操作可以啟動增強型和基本身分驗證的開發人員身分驗證。這會使用管理憑證來API驗證請求。Logins 映射是身分集區開發人員提供者名稱,如同與自訂識別符login.mydevprovider配對。

範例:

"Logins": { "login.mydevprovider": "my developer identifier" }

增強型身分驗證

使用具有來自 之權杖名稱cognito-identity.amazonaws.com和值的Logins映射呼叫 GetCredentialsForIdentityAPI操作GetOpenIdTokenForDeveloperIdentity

範例:

"Logins": { "cognito-identity.amazonaws.com": "eyJra12345EXAMPLE" }

GetCredentialsForIdentity 使用開發人員驗證身分,會傳回身分集區預設驗證角色的臨時憑證。

基本身分驗證

呼叫 AssumeRoleWithWebIdentityAPI操作,並請求具有定義適當信任關係RoleArn的任何IAM角色的 。 角色信任和許可將 的值WebIdentityToken設定為從 取得的權杖GetOpenIdTokenForDeveloperIdentity

如需開發人員驗證身分驗證 authflow 以及它們與外部提供者身分差異的相關資訊,請參閱 身分集區身分驗證流程

定義開發供應商名稱,並將其與身分集區建立關聯

若要使用開發人員驗證的身分,您需要有與開發供應商相關聯的身分池。若要執行此作業,請遵循下列步驟:

若要新增自訂開發供應商
  1. Amazon Cognito 主控台選擇 身分池。選取身分池。

  2. 選擇 使用者存取權 索引標籤。

  3. 選取 新增身分供應商

  4. 選擇 自訂開發人員提供者

  5. 輸入 開發人員供應商名稱。新增開發供應商之後,您無法變更或刪除。

  6. 選取儲存變更

備註:一旦設定供應商名稱,就無法再變更。

如需使用 Amazon Cognito 主控台的其他指示,請參閱使用 Amazon Cognito 主控台

實作身分提供者

Android

若要使用開發人員驗證的身分,請實作您自己的身分供應商類別,擴展 AWSAbstractCognitoIdentityProvider。您的身分供應商類別應傳回包含字符做為屬性的回應物件。

下列是基礎身分提供者範例。

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; } } }

若要使用此身分提供者,您必須將其傳入 CognitoCachingCredentialsProvider。範例如下:

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

iOS - Objective-C

若要使用開發人員驗證身分,請實作延伸 的身分提供者類別AWSCognitoCredentialsProviderHelper。您的身分提供者類別應傳回包含權杖做為屬性的回應物件。

@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

若要使用此身分提供者,請將其傳入 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。您的身分提供者類別應傳回包含權杖做為屬性的回應物件。

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) }

若要使用此身分提供者,請將其傳入 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' 的簡單範例:

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); } }

上述程式碼使用執行緒發送器物件來呼叫 coroutine。如果無法在您的專案中這麼做,您可以在您的場景中使用下列指令碼:

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' 的基礎範例:

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

在向您的身分驗證系統成功驗證使用者之後,請更新登入對應中的開發人員供應商名稱和開發使用者識別符。開發使用者識別符是英數字串,可唯一識別的身分驗證系統中的使用者。更新登入後,請務必呼叫 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 取得新的憑證 (例如,您的最終使用者從未驗證到已驗證,而且您想要針對已驗證的使用者取得憑證),請在 clearCredentials上呼叫 credentialsProvider

[credentialsProvider clearCredentials];

iOS - Swift

iOS SDK只會呼叫您的logins方法,以便在沒有登入資料或登入資料過期時取得最新的登入映射。如果您想要強制 SDK 取得新的憑證 (例如,您的最終使用者從未驗證到已驗證,而且您想要針對已驗證的使用者取得憑證),請在 clearCredentials上呼叫 credentialsProvider

credentialsProvider.clearCredentials()

取得權杖 (伺服器端)

您可以呼叫 來取得權杖GetOpenIdTokenForDeveloperIdentity。這API必須使用 AWS 開發人員憑證從後端叫用。不得從用戶端 叫用它SDK。API 會接收 Cognito 身分集區 ID;包含身分提供者名稱作為索引鍵和識別符作為值的登入映射;以及選用的 Cognito 身分 ID (例如,您要讓未經驗證的使用者進行身分驗證)。識別符可以是使用者的使用者名稱、電子郵件地址或數值。會使用使用者的唯一 Cognito ID 和最終使用者的 OpenID Connect 權杖來API回應您的通話。

關於 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 //...

按照上述步驟,您應該能夠將開發人員驗證的身分整合在您的應用程式。如果您有任何問題,請隨時張貼在我們的論壇中。

連接至現有的社交身分

當您使用開發人員驗證的身分時,供應商的所有連結都必須從您的後端完成。若要將自訂身分連線至使用者的社交身分 (使用 Amazon 登入、使用 Apple、Facebook 或 Google 登入),請在呼叫 時將身分提供者權杖新增至登入地圖GetOpenIdTokenForDeveloperIdentity。為了實現這一點,當您從用戶端呼叫後端SDK以驗證最終使用者時,請另外傳遞最終使用者的社交提供者權杖。

例如,如果您嘗試將自訂身分連結至 Facebook,當您呼叫 GetOpenIdTokenForDeveloperIdentity時,除了身分提供者識別符,也要將 Facebook 權杖新增至登入對應。

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

支援供應商之間的轉換

Android

您的應用程式可能需要支援未驗證的身分或使用公有身分供應商 (Login with Amazon、Sign in with Apple、Facebook 或 Google) 驗證的身分,以及開發人員驗證的身分。開發人員驗證身分和其他身分 (使用公有提供者的未驗證身分和驗證身分) 之間的基本差異,是取得 identityId 和 權杖的方式。針對其他身分,行動應用程式會直接與 Amazon Cognito 互動,而不會聯絡您的身分驗證系統。所以行動應用程式應該能夠依據應用程式使用者的選擇,支援兩種不同的流程。因此,您必須對自訂身分供應商進行一些變更。

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方法也會有兩個流程:

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、Sign in with Apple、Facebook 或 Google) 驗證的身分,以及開發人員驗證的身分。若要這麼做,請覆寫 AWSCognitoCredentialsProviderHelper logins 方法,以便能夠根據目前的身分提供者傳回正確的登入映射。此範例說明如何在未驗證、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 取得新的驗證憑證。如果您在兩個已驗證的供應商之間切換,而不嘗試將這兩個供應商連結 (例如,您不要在登入字典中提供多個供應商的權杖),則應呼叫 [credentialsProvider clearKeychain];。這將同時清除憑證和身分,並強制 SDK 取得新的憑證和身分。

iOS - Swift

您的應用程式可能需要支援未驗證的身分或使用公有身分供應商 (Login with Amazon、Sign in with Apple、Facebook 或 Google) 驗證的身分,以及開發人員驗證的身分。若要這麼做,請覆寫 AWSCognitoCredentialsProviderHelper logins 方法,以便能夠根據目前的身分提供者傳回正確的登入映射。此範例說明如何在未驗證、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 取得新的驗證憑證。如果您在兩個已驗證的供應商之間切換,而不嘗試將這兩個供應商連結 (也就是說,您不要在登入字典中提供多個供應商的權杖),則應呼叫 credentialsProvider.clearKeychain()。這將同時清除憑證和身分,並強制 SDK 取得新的憑證和身分。

Unity

您的應用程式可能需要支援未驗證的身分或使用公有身分供應商 (Login with Amazon、Sign in with Apple、Facebook 或 Google) 驗證的身分,以及開發人員驗證的身分。開發人員驗證身分和其他身分 (使用公有提供者的未驗證身分和驗證身分) 之間的基本差異,是取得 identityId 和 權杖的方式。針對其他身分,行動應用程式會直接與 Amazon Cognito 互動,而不會聯絡您的身分驗證系統。行動應用程式應該能夠依據應用程式使用者的選擇,支援兩種不同的流程。因此,您必須對自訂身分供應商進行一些變更。

在 Unity 中執行此操作的建議方法是從 延伸身分提供者 AmazonCognitoEnhancedIdentityProvide ,而不是 AbstractCognitoIdentityProvider,並呼叫父 RefreshAsync 方法,而不是您自己的方法,以防使用者沒有使用您自己的後端進行身分驗證。如果使用者已驗證,則您可以使用先前說明的相同流程。

Xamarin

您的應用程式可能需要支援未驗證的身分或使用公有身分供應商 (Login with Amazon、Sign in with Apple、Facebook 或 Google) 驗證的身分,以及開發人員驗證的身分。開發人員驗證身分和其他身分 (使用公有提供者的未驗證身分和驗證身分) 之間的基本差異,是取得 identityId 和 權杖的方式。針對其他身分,行動應用程式會直接與 Amazon Cognito 互動,而不會聯絡您的身分驗證系統。行動應用程式應該能夠依據應用程式使用者的選擇,支援兩種不同的流程。因此,您必須對自訂身分供應商進行一些變更。