返回文章列表

Amazon Cognito 聯合身份驗證實務

本文探討如何使用 Amazon Cognito 建立安全可靠的聯合身份驗證機制,讓使用者能以 Google 帳號登入應用程式,並示範如何取得 AWS 臨時憑證以存取 AWS 資源。同時,文章也涵蓋了使用 AWS Certificate Manager (ACM) 申請和管理 SSL/TLS

Web 開發 資安

現今應用程式普遍整合第三方登入以提升使用者經驗,Amazon Cognito 提供簡化的身份管理和存取控制方案。本文將引導開發者使用 Cognito 建立聯合身份驗證,允許使用者以 Google 帳號登入,並取得臨時憑證以操作 AWS 服務。同時,我們也將探討如何透過 AWS Certificate Manager (ACM) 申請 SSL/TLS 憑證,保障資料傳輸安全,強化應用程式整體安全性。文章將涵蓋 AWS CLI 及 CloudFormation 的操作,提供更彈性的佈署方式。

使用 Amazon Cognito 實作聯合身份驗證

在現代的應用程式開發中,使用者身份驗證是一個非常重要的環節。Amazon Cognito 提供了一種簡便的方式來管理使用者身份和存取控制。在本章中,我們將探討如何使用 Amazon Cognito 實作聯合身份驗證。

聯合身份驗證的概念

聯合身份驗證是一種允許使用者使用其他身份提供者的憑證登入到我們的系統中的過程。例如,我們可以使用 Google 或 Facebook 的帳戶來登入我們的應用程式。

使用 Amazon Cognito 實作聯合身份驗證

要使用 Amazon Cognito 實作聯合身份驗證,我們需要完成以下幾個步驟:

步驟 1:組態身份提供者(Google Plus)

  1. 前往 https://console.developers.google.com 並接受條款和條件。
  2. 選擇 Google+ API 並啟用它。
  3. 建立一個新的 OAuth 客戶端 ID。
  4. 組態同意畫面並儲存。
  5. 建立一個 Web 應用程式型別的 OAuth 客戶端 ID。

步驟 2:建立和組態 Identity Pool

  1. 建立一個 provider.json 檔案,包含 Google 的提供者名稱和客戶端 ID。
{
  "accounts.google.com": "55367180174-6brhjc2v6kdllcejabnr1e46957f72te.apps.googleusercontent.com"
}
  1. 使用 AWS CLI 建立一個 Identity Pool。
aws cognito-identity create-identity-pool \
  --identity-pool-name qnatimepool \
  --no-allow-unauthenticated-identities \
  --supported-login-providers file://provider.json \
  --profile admin
  1. 建立一個允許必要許可權給使用者的政策。
aws iam create-policy \
  --policy-name identity-pool-policy \
  --policy-document file://role_policy.txt \
  --profile admin

role_policy.txt 的內容如下:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "mobileanalytics:PutEvents",
        "cognito-sync:*",
        "cognito-identity:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
  1. 建立一個名為 identity-pool-role 的角色並附加政策到該角色。

使用 JavaScript SDK 實作使用者登入流程

我們可以使用 Amazon Cognito 的 JavaScript SDK 來實作使用者登入流程。以下是一個簡單的範例:

var authenticationData = {
  Username: 'heartin',
  Password: '<password>',
};
var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
var poolData = {
  UserPoolId: '<user pool id>',
  ClientId: '<client id>'
};
var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
var userData = {
  Username: 'heartin',
  Pool: userPool
};
var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
  onSuccess: function(result) {
    var accessToken = result.getAccessToken().getJwtToken();
    console.log('access token is:' + accessToken);
  },
  onFailure: function(err) {
    console.log(JSON.stringify(err));
    alert(err.message || JSON.stringify(err));
  },
});

程式碼解密:

  1. 首先,我們定義了 authenticationData 物件,包含使用者的使用者名稱和密碼。
  2. 然後,我們建立了一個 AuthenticationDetails 物件,並將 authenticationData 傳遞給它。
  3. 接下來,我們定義了 poolData 物件,包含使用者池的 ID 和客戶端 ID。
  4. 我們建立了一個 CognitoUserPool 物件,並將 poolData 傳遞給它。
  5. 然後,我們定義了 userData 物件,包含使用者的使用者名稱和 CognitoUserPool 物件。
  6. 我們建立了一個 CognitoUser 物件,並將 userData 傳遞給它。
  7. 最後,我們呼叫了 authenticateUser 方法,並傳遞了 authenticationDetails 和回呼函式。

使用 AWS Cognito 實作身分驗證與授權

概述

本章節將介紹如何使用 AWS Cognito 實作身分驗證與授權,並透過 Google 登入取得臨時憑證以存取 AWS 服務。同時,我們也會探討如何使用 AWS Certificate Manager (ACM) 建立 SSL/TLS 憑證。

步驟 1:設定 AWS Cognito 身分池

首先,我們需要建立一個 Cognito 身分池,並設定其角色。

aws cognito-identity create-identity-pool \
--identity-pool-name QNAIdentityPool \
--allow-unauthenticated-identities \
--region us-east-1 \
--profile admin

接著,建立一個 roles.json 檔案,定義授權角色:

{
  "authenticated": "arn:aws:iam::123456789012:role/Cognito_QNAIdentityPoolAuth_Role",
  "unauthenticated": "arn:aws:iam::123456789012:role/Cognito_QNAIdentityPoolUnauth_Role"
}

將角色附加到身分池:

aws cognito-identity set-identity-pool-roles \
--identity-pool-id <your identity pool id> \
--roles file://roles.json \
--region us-east-1 \
--profile admin

內容解密:

  • create-identity-pool 命令用於建立一個新的 Cognito 身分池。
  • set-identity-pool-roles 命令用於設定身分池的授權角色。
  • roles.json 檔案定義了已驗證和未驗證使用者的 IAM 角色。

步驟 2:準備與上傳程式碼檔案

我們需要兩個 HTML 檔案:index.htmlerror.htmlindex.html 將包含主要的登入頁面,而 error.html 用於處理錯誤。

index.html 檔案內容

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>QNA Time</title>
  <script src="https://apis.google.com/js/platform.js" async defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/aws-sdk/2.390.0/aws-sdk.min.js"></script>
  <meta name="google-signin-client_id" content="1056864857699-i6ami0u5oevpn9bro2k3r095jtqohdi7.apps.googleusercontent.com"/>
</head>
<body>
  <span style="text-align:center;"><h1>Welcome to QNA TIME</h1></span>
  <form>
    <div style="width:200px;" class="g-signin2" data-onsuccess="onSignIn"></div>
  </form>

  <script type="text/javascript">
    var id_token;
    var identity;
    var cognitoidentity = new AWS.CognitoIdentity({ region: "us-east-1" });

    function getCredentials() {
      var params1 = {
        IdentityId: identity,
        Logins: {
          "accounts.google.com": id_token
        }
      };
      cognitoidentity.getCredentialsForIdentity(params1, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
          console.log(data);
          console.log(data.Credentials.AccessKeyId);
        }
      });
    }

    function onSignIn(googleUser) {
      id_token = googleUser.getAuthResponse().id_token;
      console.log("google_id_token:" + id_token);
      var params = {
        IdentityPoolId: "us-east-1:f36a0555-fd35-43d6-bafa-187ecdef0f04",
        Logins: {
          "accounts.google.com": id_token
        }
      };
      cognitoidentity.getId(params, function(err, data) {
        if (err) console.log(err, err.stack);
        else {
          console.log(data);
          identity = data.IdentityId;
          getCredentials();
        }
      });
    }
  </script>
</body>
</html>

內容解密:

  • index.html 檔案包含 Google 登入按鈕,並使用 AWS SDK 進行身分驗證。
  • onSignIn 函式在使用者成功登入後被呼叫,取得 Google ID Token 並使用 Cognito 取得臨時憑證。
  • getCredentials 函式使用 Cognito 身分 ID 和 Google ID Token 取得臨時 AWS 憑證。

使用 ACM 建立 SSL/TLS 憑證

AWS Certificate Manager (ACM) 提供了一種簡便的方式來建立和管理 SSL/TLS 憑證。

使用 AWS CLI 建立憑證

aws acm request-certificate \
--domain-name example.com \
--validation-method DNS \
--region us-east-1

使用 CloudFormation 建立憑證

Resources:
  Certificate:
    Type: 'AWS::CertificateManager::Certificate'
    Properties:
      DomainName: example.com
      ValidationMethod: DNS

內容解密:

  • request-certificate 命令用於請求一個新的 SSL/TLS 憑證。
  • CloudFormation 範本定義了一個 AWS::CertificateManager::Certificate 資源,用於建立憑證。

使用AWS Certificate Manager申請SSL/TLS憑證的完整

在現代的網路應用中,確保資料傳輸的安全性是至關重要的。AWS Certificate Manager(ACM)提供了一種簡便的方式來申請和管理SSL/TLS憑證。本文將詳細介紹如何使用AWS CLI和CloudFormation來申請和管理憑證。

步驟一:使用AWS CLI申請憑證

首先,我們需要使用AWS CLI來請求一個SSL/TLS憑證。可以使用以下命令:

aws acm request-certificate \
--domain-name www.qnatime.net \
--validation-method DNS \
--profile admin

此命令會請求一個憑證並指定驗證方法為DNS。AWS提供了兩種驗證方法:DNS和電子郵件。DNS驗證是首選方法,因為它更為方便和安全。

內容解密:

  • aws acm request-certificate:用於請求一個新的憑證。
  • --domain-name:指定需要申請憑證的網域名稱。
  • --validation-method DNS:選擇DNS作為驗證方法。
  • --profile admin:指定使用的AWS組態檔。

步驟二:檢查憑證狀態

申請憑證後,可以使用以下命令來檢查憑證的狀態:

aws acm describe-certificate \
--certificate-arn arn:aws:acm:us-east-1:218317422462:certificate/42b3ba99-66e9-4e71-8c1c-4239c1e81c84 \
--profile admin

這個命令會傳回憑證的詳細資訊,包括驗證狀態。

內容解密:

  • aws acm describe-certificate:用於查詢憑證的詳細資訊。
  • --certificate-arn:指定要查詢的憑證ARN。

步驟三:進行DNS驗證

要完成DNS驗證,需要在網域名稱的DNS記錄中新增一條CNAME記錄。首先,建立一個JSON檔案來定義變更批次:

{
  "Comment": "change batch request for dns validation www.qnatime.net",
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "_f086ad8e4c10e38385c3c36394a06182.www.qnatime.net.",
        "Type": "CNAME",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "_ee9788f2dcf3eaefaa85bb096163ffd4.tljzshvwok.acm-validations.aws."
          }
        ]
      }
    }
  ]
}

然後,使用以下命令更新DNS記錄:

aws route53 change-resource-record-sets \
--hosted-zone-id Z3G50MON7IDA18 \
--change-batch file://resources/change-resource-record-sets-dns-validation.json \
--profile admin

內容解密:

  • aws route53 change-resource-record-sets:用於更新DNS記錄。
  • --hosted-zone-id:指定託管區域ID。
  • --change-batch:指定包含變更批次的JSON檔案。

步驟四:使用CloudFormation自動化憑證申請

雖然憑證申請過程無法完全自動化,但可以使用CloudFormation來簡化流程。首先,建立一個CloudFormation範本來請求憑證:

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Certificate Manager'
Parameters:
  RootDomainName:
    Description: Domain name for generating certificate
    Type: String
Resources:
  RootDomainCert:
    Type: AWS::CertificateManager::Certificate
    Properties:
      DomainName: !Ref RootDomainName
      ValidationMethod: DNS
Outputs:
  CertificateArn:
    Value: !Ref RootDomainCert

然後,使用以下命令建立堆積疊:

aws cloudformation create-stack \
--stack-name certificate-stack \
--template-body file://certificate-template.yaml \
--profile admin

內容解密:

  • AWS::CertificateManager::Certificate:用於請求憑證的CloudFormation資源。
  • ValidationMethod: DNS:指定DNS作為驗證方法。