[AWS] Amazon Cognito

看懂 [AWS] User management and [AWS] OAuth2.0 才方便看到此篇。html

Ref: 常見 Amazon Cognito 場景react

Amazon Cognito 的兩個主要組件是用戶池身份池ios

  • 用戶池:是爲您的應用程序提供註冊登陸選項的用戶目錄。
  • 身份池:提供 AWS 憑證以向用戶授予對其餘 AWS 服務的訪問權限。 

 

  1. 在第一步中,您的應用程序用戶經過用戶池登陸,並在成功進行身份驗證後收到持有者令牌。[access token, id token, refresh token]git

  2. 接下來,您的應用程序經過身份池用用戶池令牌交換 AWS 憑證github

  3. 最後,您的應用程序用戶可使用這些 AWS 憑證 來訪問其餘 AWS 服務 (如 Amazon S3 或 DynamoDB)。npm

 

使用用戶池進行身份驗證

Figure, 標準化推薦訪問驗證json

 

您能夠容許您的用戶使用用戶池進行身份驗證。後端

您的用戶能夠經過用戶池直接登陸,api

也能夠經過第三方身份提供商 (IdP) 間接登陸。瀏覽器

 

用戶池管理處理如下令牌的開銷:

從經過 Facebook、Google 和 Amazon 進行的社交登陸返回的令牌,

以及從提供單點登陸解決方案 (如 Microsoft Active Directory Federation Services (ADFS)) 的 SAML 身份提供商返回的令牌。

 

成功進行身份驗證後,您的 Web 或移動應用程序將收到來自 Amazon Cognito 的持有者令牌

您可使用這些令牌檢索容許您的應用程序訪問其餘 AWS 服務的 AWS 憑證,

也能夠選擇使用它們來控制對您本身的資源或 Amazon API Gateway 的訪問

 

使用用戶池訪問您本身的資源

您能夠容許您的用戶使用來自成功的、身份驗證的、用戶池令牌訪問您本身的資源。

有關更多信息,請參閱 用戶池身份驗證流程 和 將令牌與用戶池結合使用

Figure, 訪問本身的資源

 

用戶池身份驗證流程

 

將令牌與用戶池結合使用

成功進行身份驗證後,您的 Web 或移動應用程序將收到來自 Amazon Cognito 的持有者令牌。

 身份驗證概述

如下是由 OpenID Connect 規範定義的令牌:

  • ID 令牌

  • 訪問令牌

  • 刷新令牌

 

 

使用 ID 令牌

ID 令牌以 JSON Web Token (JWT) 表示。

該令牌包含有關已驗證用戶的身份的聲明。

例如,它包含 namefamily_namephone_number 等聲明。

 

有關標準聲明的更多信息,請參閱 OpenID Connect 規範。客戶端應用程序能夠在應用程序中使用此身份信息。

此外,ID 令牌還可用於針對資源服務器或服務器應用程序對用戶進行身份驗證。

在應用程序外部將 ID 令牌用於 Web API 時,您必須先驗證 ID 令牌的簽名,而後才能信任 ID 令牌內的任何聲明。

ID 令牌會在用戶進行身份驗證後的 1 小時內過時。在 ID 令牌過時後,您不該該在客戶端或 Web API 中對其進行處理。

 

使用 ACCESS 令牌

訪問令牌也以 JSON Web Token (JWT) 表示。它也包含有關已驗證用戶的聲明,但與 ID 令牌不一樣,它不包含用戶的全部身份信息

訪問令牌的主要用途是在用戶池中用戶的環境中授予操做權限。

例如,您能夠根據用戶池使用訪問令牌更新或刪除用戶屬性。

 

此外,訪問令牌還可與任何 Web API 結合使用,以作出訪問控制決策並在用戶環境中授予操做權限。

與 ID 令牌同樣,您必須先在 Web API 中驗證訪問令牌的簽名,而後才能信任訪問令牌內的任何聲明。

訪問令牌會在用戶進行身份驗證後的 1 小時內過時。在訪問令牌過時後,您不該該對其進行處理。

 

使用刷新令牌

要使用刷新令牌獲取新令牌,請使用 InitiateAuth 或 AdminInitiateAuth API 方法。驗證流程類型爲 REFRESH_TOKEN_AUTH。受權參數 AuthParameters 是密鑰-值映射,其中密鑰爲「REFRESH_TOKEN」,值爲實際刷新令牌。

這會經過 Amazon Cognito 服務器啓動令牌刷新流程並返回新的 ID 和訪問令牌。

默認狀況下,刷新令牌會在用戶進行身份驗證後的 30 天內過時。當您爲用戶池建立應用程序時,您能夠將應用程序的 Refresh token expiration (days) 設置爲介於 1 和 3650 之間的任何值。

 

 

 

問題來了,如何讓另外一個獨立的服務歸入到現有的用戶認證系統中來? 


AWS 提供的單點登陸(SSO)

 

這裏實際出現了問題,兩個端口須要一個統一的http server來分流,統一做爲「前臺」接待用戶。

在此項目中不適合。

SSO討論到此爲止。 

 

 

 

AWS Amplify纔是將來


Goto:Quick Start

 

安裝amplify:

$ npm install --save aws-amplify
# On a React app,
in addition to aws-amplify,
# we provide helpers and higher order components that are packaged in aws-amplify-react. $ npm install --save aws-amplify-react # optional HOCs

 

 

概念理解:

AWS Mobile Hub:AWS Amplify connects to AWS Mobile Hub to work with Amazon Web Services.

AWS Mobile CLI:creates and configures new AWS resources for your backend.

$ npm install -g awsmobile-cli
# 第一次使用,則:
# To setup permissions for the toolchain used by the CLI, run:
$ awsmobile configure

onfigure aws
? accessKeyId:      <YOUR_ACCESS_KEY_ID>
? secretAccessKey:  <YOUR_SECRET_ACCESS_KEY> 

爲什麼要有accesskeyId and secretAccesskey? It seems like something for S3.

 

 

配置後端

自動配置 - 暫時不關心

手動配置 - 使人放心

Manual Setup to work with existing AWS Resources

If you want to use your existing AWS resources with your app (S3 buckets, Cognito user pools, etc.),

you need to manually configure your app with your existing credentials in your code:

就是配置最經常使用的一些aws服務:https://serverless-stack.com/chapters/configure-aws-amplify.html

Amplify.configure({
Auth: { mandatorySignIn:
true, region: config.cognito.REGION, userPoolId: config.cognito.USER_POOL_ID, identityPoolId: config.cognito.IDENTITY_POOL_ID, userPoolWebClientId: config.cognito.APP_CLIENT_ID }, Storage: { region: config.s3.REGION, bucket: config.s3.BUCKET, identityPoolId: config.cognito.IDENTITY_POOL_ID }, API: { endpoints: [ { name: "notes", endpoint: config.apiGateway.URL, region: config.apiGateway.REGION }, ] } });

 

 

Add User Authentication to Your App

Goto: https://aws.github.io/aws-amplify/media/authentication_guide

 

Automated Setup - 不放心

Manual Setup - 推薦

第一階段效果:

URL: https://dha4w82d62smt.cloudfront.net/items/2R3r0P453o2s2c2f3W2O/Screen%20Recording%202018-02-11%20at%2003.48%20PM.gif

 

 

 

[AWS] OAuth2.0


 

Ref: 理解OAuth 2.0

若干專有名詞:

(1)Third-party application:第三方應用程序,本文中又稱"客戶端"(client),即上一節例子中的"雲沖印"

(2)HTTP service:                HTTP服務提供商,本文中簡稱"服務提供商",即上一節例子中的Google

(3)Resource Owner:          資源全部者,本文中又稱"用戶"(user)。

(4)User Agent:                   用戶代理,本文中就是指 瀏覽器

(5)Authorization server:   認證服務器,即服務提供商專門用來處理認證的服務器。

(6)Resource server:          資源服務器,即服務提供商存放用戶生成的資源的服務器。它與認證服務器,能夠是同一臺服務器,也能夠是不一樣的服務器。

 

上圖第三步中的「受權」,能夠是,好比「受權碼」 + 「重定向URI」。

 

(A)用戶打開客戶端之後,客戶端要求用戶給予受權。
(B)用戶贊成給予客戶端受權。  # 最爲重要 --> 詳解
(C)客戶端使用上一步得到的受權,向認證服務器申請令牌。
(D)認證服務器對客戶端進行認證之後,確認無誤,贊成發放令牌。
(E)客戶端使用令牌,向資源服務器申請獲取資源。
(F)資源服務器確認令牌無誤,贊成向客戶端開放資源。

 

 

客戶端必須獲得用戶的受權(authorization grant),才能得到令牌access token)。

OAuth 2.0定義了四種受權方式。

  • 受權碼模式(authorization code)    # 功能最完整、流程最嚴密的受權模式
  • 簡化模式    (implicit)
  • 密碼模式    (resource owner password credentials)
  • 客戶端模式(client credentials)

 

 

資源服務器如何辨別令牌的真假?

由於有一步多是在客戶端的後端的服務器上完成的,對用戶不可見。詳情以下:

 

受權碼模式

 

 

(A)用戶訪問客戶端,後者將前者導向認證服務器。客戶端申請認證的URI,包含如下參數:
    • response_type:表示受權類型,必選項,此處的值固定爲"code"
    • client_id:    表示客戶端的ID,必選項
    • redirect_uri: 表示重定向URI,可選項
    • scope:        表示申請的權限範圍,可選項
    • state:        表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值。
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz
                 &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
 Host: server.example.com

(B)用戶選擇是否給予客戶端受權。
(C)假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(redirection URI),同時附上一個受權碼。迴應URI
    • code: 表示受權碼,必選項。

                  該碼的有效期應該很短,一般設爲10分鐘,客戶端只能使用該碼一次,不然會被受權服務器拒絕。

                  該碼與客戶端ID和重定向URI,是一一對應關係。

    • state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。
HTTP/1.1 302 Found
 Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz

(D)客戶端收到受權碼,附上早先的"重定向URI",向認證服務器申請令牌。這一步是在客戶端的後臺的服務器上完成的,對用戶不可見。
    • grant_type:  表示使用的受權模式,必選項,此處的值固定爲"authorization_code"。
    • code:        表示上一步得到的受權碼,必選項。
    • redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該參數值保持一致。
    • client_id:   表示客戶端ID,必選項。
POST /token HTTP/1.1
 Host: server.example.com  Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW  Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

(E)認證服務器覈對了受權碼和重定向URI,確認無誤後,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)。
    • access_token: 表示訪問令牌,必選項。
    • token_type:   表示令牌類型,該值大小寫不敏感,必選項,能夠是bearer類型或mac類型。
    • expires_in:   表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。
    • refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項。
    • scope:        表示權限範圍,若是與客戶端申請的範圍一致,此項可省略。 
HTTP/1.1 200 OK
        Content-Type: application/json;charset=UTF-8
        Cache-Control: no-store
        Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }

 

 

簡化模式

簡化模式(implicit grant type)不經過第三方應用程序的服務器,直接在瀏覽器中向認證服務器申請令牌,

跳過了"受權碼"這個步驟,所以得名。全部步驟在瀏覽器中完成,令牌對訪問者是可見的,且客戶端不須要認證。 

 

(A)客戶端將用戶導向認證服務器。
    • response_type:表示受權類型,此處的值固定爲"token",必選項。
    • client_id:    表示客戶端的ID,必選項。
    • redirect_uri: 表示重定向的URI,可選項。
    • scope:        表示權限範圍,可選項。
    • state:        表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值。
 
 
GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
            &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
        Host: server.example.com

(B)用戶決定是否給於客戶端受權。
(C)假設用戶給予受權,認證服務器將用戶導向客戶端指定的"重定向URI"並在URI的Hash部分包含了訪問令牌
[簡化去掉了「受權碼」,直接得到了隱藏在hash值中的令牌,瀏覽器此時無法提取令牌]
    • access_token:表示訪問令牌,必選項。
    • token_type:  表示令牌類型,該值大小寫不敏感,必選項。
    • expires_in:  表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。
    • scope:       表示權限範圍,若是與客戶端申請的範圍一致,此項可省略。
    • state:       若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。
 
 
HTTP/1.1 302 Found
         Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA
                   &state=xyz&token_type=example&expires_in=3600

(D)瀏覽器向資源服務器發出請求,其中不包括上一步收到的Hash值。 
(E)資源服務器返回一個網頁,其中包含的代碼能夠獲取Hash值中的令牌。
(F)瀏覽器執行上一步得到的腳本,提取出令牌
(G)瀏覽器將令牌發給客戶端。

 

 

密碼模式

在這種模式中,用戶必須把本身的密碼給客戶端,可是客戶端不得儲存密碼。

這一般用在用戶對客戶端高度信任的狀況下,好比客戶端是操做系統的一部分,或者由一個著名公司出品。

認證服務器只有在其餘受權模式沒法執行的狀況下,才能考慮使用這種模式。 

 

整個過程當中,客戶端不得保存用戶的密碼。

(A)用戶向客戶端提供用戶名和密碼。

(B)客戶端將用戶名和密碼發給認證服務器,向後者請求令牌。
    • grant_type:表示受權類型,此處的值固定爲"password",必選項。
    • username:  表示用戶名,必選項。
    • password:  表示用戶的密碼,必選項。
    • scope:     表示權限範圍,可選項。 

POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=password&username=johndoe&password=A3ddj3w

(C)認證服務器確認無誤後,向客戶端提供訪問令牌。
HTTP/1.1 200 OK
     Content-Type: application/json;charset=UTF-8
     Cache-Control: no-store
     Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }

 

 

客戶端模式

客戶端模式(Client Credentials Grant)指客戶端以本身的名義,而不是以用戶的名義,向"服務提供商"進行認證。

嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。

在這種模式中,用戶直接向客戶端註冊,客戶端以本身的名義要求"服務提供商"提供服務,其實不存在受權問題。

 

(A)客戶端向認證服務器進行身份認證,並要求一個訪問令牌。客戶端發出的HTTP請求,包含如下參數:
    • granttype:表示受權類型,此處的值固定爲"clientcredentials",必選項。
    • scope:表示權限範圍,可選項。
 
 
POST /token HTTP/1.1
        Host: server.example.com
        Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
        Content-Type: application/x-www-form-urlencoded

        grant_type=client_credentials
 
 
(B)認證服務器確認無誤後,向客戶端提供訪問令牌。
 HTTP/1.1 200 OK
       Content-Type: application/json;charset=UTF-8
       Cache-Control: no-store
       Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "example_parameter":"example_value" }

 

 

更新令牌

若是用戶訪問的時候,客戶端的"訪問令牌"已通過期,則須要使用"更新令牌"申請一個新的訪問令牌。

客戶端發出更新令牌的HTTP請求,包含如下參數:

granttype:    表示使用的受權模式,此處的值固定爲"refreshtoken",必選項。
refresh_token:表示早前收到的更新令牌,必選項。
scope:        表示申請的受權範圍,不能夠超出上一次申請的範圍,若是省略該參數,則表示與上一次一致

下面是一個例子。

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
相關文章
相關標籤/搜索