Identity And Security Control In Cloud

企業(yè)上云首當其沖的就是要考量安全性的問題。為了保證系統(tǒng)的安全,和數(shù)據(jù)的安全,公司必須制定訪問控制策略。首先看看現(xiàn)在的云平臺對于身份認證與訪問控制的設(shè)計。

Microsoft Azure

Azure 資源的基于角色的訪問控制 (RBAC)

Role-Based Access Control :其基本思想是,對系統(tǒng)操作的各種權(quán)限不是直接授予具體的用戶,而是在用戶集合與權(quán)限集合之間建立一個角色集合。每一種角色對應(yīng)一組相應(yīng)的權(quán)限。一旦用戶被分配了適當?shù)慕巧?,該用戶就擁有此角色的所有操作?quán)限。

RBAC 的作用示例

  • 讓一個用戶管理訂閱中的虛擬機,另一個用戶管理虛擬網(wǎng)絡(luò)
  • 讓 DBA 組管理訂閱中的 SQL 數(shù)據(jù)庫
  • 讓某個用戶管理資源組中的所有資源,例如虛擬機、網(wǎng)站和子網(wǎng)
  • 允許某個應(yīng)用程序訪問資源組中的所有資源

Azure提到使用RBAC的最佳做法是授予用戶完成工作所需的最低權(quán)限。使用 RBAC,可以在團隊中實現(xiàn)職責分離,僅向用戶授予執(zhí)行作業(yè)所需的訪問權(quán)限。 無需向每個人授予 Azure 訂閱或資源的無限制權(quán)限,可以僅允許在特定的范圍執(zhí)行某些操作。

RBAC使用有關(guān)的建議模式

RBAC 的工作原理

RBAC 控制資源訪問權(quán)限的方式是創(chuàng)建角色分配。角色分配包含三個要素:安全主體(Security Principal)、角色定義(Role Definition)和范圍(Scope)。

安全主體(Security Principal)

安全主體是一個對象,表示請求訪問 Azure 資源的用戶、組、服務(wù)主體或托管標識。


image.png
  • 用戶(User) - 在 Azure Active Directory 中具有配置文件的人員。
  • 組(Group) - 在 Azure Active Directory 中創(chuàng)建的一組用戶。 將某個角色分配到某個組時,該組中的所有用戶都擁有該角色。
  • 服務(wù)主體(Service principal) - 應(yīng)用程序或服務(wù)用來訪問特定 Azure 資源的安全標識。 可將服務(wù)主體視為應(yīng)用程序的用戶標識(用戶名和密碼或證書)。
  • 托管標識(Managed identity) - Azure Active Directory 中由 Azure 自動托管的標識。 在開發(fā)云應(yīng)用程序時,通常使用托管標識來管理用于向 Azure 服務(wù)進行身份驗證的憑據(jù)。

角色定義(Role Definition)
角色定義是權(quán)限的集合。角色定義列出可以執(zhí)行的操作,例如讀取、寫入和刪除。

Role Definition

Azure 包含多個可用的內(nèi)置角色。分別擁有相應(yīng)的權(quán)限。例如下面四個基本的內(nèi)置角色。

  • 所有者 - 擁有對所有資源的完全訪問權(quán)限,包括將訪問權(quán)限委派給其他用戶的權(quán)限。
  • 參與者 - 可以創(chuàng)建和管理所有類型的 Azure 資源,但無法將訪問權(quán)限授予其他用戶。
  • 讀取者 - 可以查看現(xiàn)有的 Azure 資源。
  • 用戶訪問管理員 - 可以管理用戶對 Azure 資源的訪問。

范圍(Scope)

角色分配是出于授予訪問權(quán)限的目的,將角色定義附加到特定范圍內(nèi)的用戶、組、服務(wù)主體或托管標識的過程。 通過創(chuàng)建角色分配來授予訪問權(quán)限,通過刪除角色分配來撤銷訪問權(quán)限。
下圖顯示了角色分配的示例。 在此示例中,為“營銷”組分配了醫(yī)藥銷售資源組的參與者角色。 這意味著,“營銷”組中的用戶可以在醫(yī)藥銷售資源組中創(chuàng)建或管理任何 Azure 資源。

Example

RBAC 是一個加法模型,生效的權(quán)限是角色分配相加。其中在訂閱范圍內(nèi)向用戶授予了“參與者”角色,并且授予了對資源組的“讀者”角色。 “參與者”權(quán)限與“讀者”權(quán)限相加實際上是資源組的“參與者”角色。 因此,在這種情況下,“讀者”角色分配沒有任何影響。

Example

更加重要是Azue RBAC是如何確定用戶是否有權(quán)限訪問資源
步驟:

  1. 用戶(或服務(wù)主體)獲取 Azure 資源管理器的令牌。令牌包含用戶的組成員身份(包括可傳遞的組成員身份)。
  2. 用戶使用附加的令牌對 Azure 資源管理器發(fā)出 REST API 調(diào)用。
  3. Azure 資源管理器檢索適用于對其執(zhí)行操作的資源的所有角色分配和拒絕分配。
  4. Azure 資源管理器縮小適用于此用戶或其組的角色分配范圍,并確定用戶針對此資源擁有的角色。
  5. Azure 資源管理器確定 API 調(diào)用中的操作是否包含在用戶針對此資源擁有的角色中。
  6. 如果用戶在請求的范圍內(nèi)沒有具有該操作的角色,則不授予訪問權(quán)限。 否則,Azure 資源管理器會檢查是否適用拒絕分配。
  7. 如果拒絕分配適用,則阻止訪問。 否則授予訪問權(quán)限。

阿里云

訪問控制(RAM)

訪問控制(Resource Access Management)是阿里云提供的管理用戶身份與資源訪問權(quán)限的服務(wù)。RAM也是按需為用戶分配最小權(quán)限。
RAM的功能特性如下:

  • 集中控制RAM用戶及其密鑰:管理每個RAM用戶及其訪問密鑰,為用戶綁定多因素認證(MFA)設(shè)備。
  • 集中控制RAM用戶的訪問權(quán)限:控制每個RAM用戶訪問資源的權(quán)限。
  • 集中控制RAM用戶的資源訪問方式:確保RAM用戶在指定的時間和網(wǎng)絡(luò)環(huán)境下,通過安全信道訪問特定的阿里云資源。
  • 集中控制云資源:對RAM用戶創(chuàng)建的實例或數(shù)據(jù)進行集中控制。當用戶離開組織時,實例或數(shù)據(jù)不會丟失。
  • 單點登錄管理(SSO):支持與企業(yè)身份提供商(IdP)進行用戶SSO或角色SSO。

RAM 的工作原理

RAM的主要要素是RAM用戶,用戶組,RAM角色。

RAM用戶
RAM用戶是RAM中的一種身份,對應(yīng)某一個操作實體(運維操作人員或應(yīng)用程序)。通過創(chuàng)建新的RAM用戶并授權(quán),RAM用戶便可以訪問相關(guān)資源。有確定的身份ID和身份憑證,它通常與某個確定的人或應(yīng)用程序一一對應(yīng)。

  • 用戶管理與分權(quán)
    當企業(yè)有多種云資源時,使用RAM的身份管理與權(quán)限管理功能,實現(xiàn)用戶分權(quán)及資源統(tǒng)一管理。


    用戶管理與分權(quán)

用戶組
若云賬號下有多個RAM用戶,通過創(chuàng)建用戶組對職責相同的RAM用戶進行分類并授權(quán),從而更好的管理用戶及其權(quán)限。

RAM角色
RAM角色有確定的身份,可以被賦予一組權(quán)限策略,但沒有確定的登錄密碼或訪問密鑰。RAM角色需要被一個受信的實體用戶扮演,扮演成功后實體用戶將獲得RAM角色的安全令牌,使用這個安全令牌就能以角色身份訪問被授權(quán)的資源。

  • 角色ARN(Role ARN)
    ARN是角色的全局資源描述符,用來指定具體角色。ARN遵循阿里云ARN的命名規(guī)范。例如,某個云賬號下的devops角色的ARN為:acs:ram::123456789012****:role/samplerole。

  • 可信實體(Trusted entity)
    角色的可信實體是指可以扮演角色的實體用戶身份。創(chuàng)建角色時必須指定可信實體,角色只能被受信的實體扮演??尚艑嶓w可以是受信的阿里云賬號、受信的阿里云服務(wù)或身份提供商。

  • 權(quán)限策略(Policy)
    一個角色可以綁定一組權(quán)限策略。沒有綁定權(quán)限策略的角色也可以存在,但不能訪問資源。
    RAM中權(quán)限策略的語法和結(jié)構(gòu) 可以自己查看
    其中權(quán)限策略結(jié)構(gòu)包括:版本號,授權(quán)語句列表。每條授權(quán)語句包括授權(quán)效力(Effect)、操作(Action)、資源(Resource)以及限制條件(Condition,可選項)。

    image.png

    權(quán)限策略模型可以分為兩種:
    云賬號內(nèi)授權(quán)模型
    image.png

    資源組內(nèi)授權(quán)模型
    image.png

  • 扮演角色(Assume role)
    扮演角色是實體用戶獲取角色身份的安全令牌的方法。一個實體用戶調(diào)用STS API AssumeRole可以獲得角色的安全令牌,使用安全令牌可以訪問云服務(wù)API。

  • 角色令牌(Role token)
    角色令牌是角色身份的一種臨時訪問密鑰。角色身份沒有確定的訪問密鑰,當一個實體用戶要使用角色時,必須通過扮演角色來獲取對應(yīng)的角色令牌,然后使用角色令牌來調(diào)用阿里云服務(wù)API。

RAM角色的使用方法

  1. RAM角色指定可信實體,即指定可以扮演角色的實體用戶身份。

  2. 可信實體通過控制臺或調(diào)用API扮演角色并獲取角色令牌。


    說明 扮演角色是實體用戶獲取RAM角色令牌的方法,角色令牌是角色身份的一種臨時訪問憑證,使用角色令牌可以訪問阿里云資源。

  3. 為RAM角色綁定權(quán)限策略

    說明 一個RAM角色可以綁定一組權(quán)限策略,沒有綁定權(quán)限策略的角色也可以存在,但不能訪問資源。

  4. 受信實體通過扮演角色,使用角色令牌訪問阿里云資源。

可以看出Azure 與阿里云 實現(xiàn)訪問控制的模型上大同小異

訪問控制身份認證實現(xiàn)

阿里云

阿里云的訪問控制:單點登錄(SSO),開放授權(quán)管理(OAuth);
點擊可以參考 SSO 和 OAuth 原理
無論哪種方式登錄的API,RAM服務(wù)會對每個訪問的請求進行身份驗證,無論使用HTTP還是HTTPS協(xié)議提交請求,都需要在請求中包含簽名信息。

RAM計算簽名

RAM通過使用AccessKey ID和AccessKeySecret進行對稱加密的方法來驗證請求的發(fā)送者身份。AccessKey ID和AccessKeySecret由阿里云頒發(fā)給訪問者,其中AccessKey ID用于標識訪問者的身份,AccessKeySecret用于加密簽名字符串和服務(wù)器端驗證簽名字符串的密鑰,必須嚴格保密謹防泄露。API網(wǎng)關(guān)計算簽名例子

計算簽名可以

  • 校驗請求參數(shù)是否被篡改。
  • 請求來源是否合法。
  • 請求是否具有唯一性。

它要求調(diào)用方按照約定好的算法生成簽名字符串,作為請求的一部分,接口提供方驗算簽名即可知是否合法。
那么如果一個系統(tǒng)也要實現(xiàn)計算簽名該怎么做呢?
主要步驟:

  1. 接口提供方給出appKey和appSecret
  2. 調(diào)用方根據(jù)appId和appSecret以及請求參數(shù),按照一定算法生成簽名sign
  3. 接口提供方驗證簽名

生成簽名的步驟如下:

1.將所有業(yè)務(wù)請求參數(shù)按字母先后順序排序
2.參數(shù)名稱和參數(shù)值鏈接成一個字符串A
3.在字符串A的首尾加上appSecret組成一個新字符串B
4.對字符串進行HmacSHA256得到簽名sign
5.使用Base64生產(chǎn)簽名字符串

看看阿里云API網(wǎng)關(guān)設(shè)置的簽名的元素有哪些
系統(tǒng)級 Header
【必選】X-Ca-Key:AppKey。
【必選】X-Ca-Signature:簽名字符串。
【可選】X-Ca-Timestamp:API 調(diào)用者傳遞時間戳,值為當前時間的毫秒數(shù),也就是從1970年1月1日起至今的時間轉(zhuǎn)換為毫秒,時間戳有效時間為15分鐘。(保證請求的唯一性
【可選】X-Ca-Nonce:API 調(diào)用者生成的 UUID,結(jié)合時間戳防重放。
【可選】Content-MD5 當請求 Body 非 Form 表單時,可以計算 Body 的 MD5 值傳遞給云網(wǎng)關(guān)進行 Body MD5 校驗。(防止內(nèi)容別篡改
【可選】X-Ca-Stage請求 API 所屬 Stage,目前僅支持 TEST 、PRE 和 RELEASE,默認RELEASE,若您調(diào)用的 API 不在線上環(huán)境,請一定要指定該參數(shù)的值,否則會報 URL 錯誤。

Example:
httpget

public static Response httpGet(String host, String path, int connectTimeout, Map<String, String> headers, Map<String, String> querys, List<String> signHeaderPrefixList, String appKey, String appSecret)
            throws Exception {
        headers = initialBasicHeader(HttpMethod.GET, path, headers, querys, null, signHeaderPrefixList, appKey, appSecret);

        HttpClient httpClient = wrapClient(host);
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, getTimeout(connectTimeout));

        HttpGet get = new HttpGet(initUrl(host, path, querys));

        for (Map.Entry<String, String> e : headers.entrySet()) {
            get.addHeader(e.getKey(), MessageDigestUtil.utf8ToIso88591(e.getValue()));
        }

        return convert(httpClient.execute(get));
    }

initialBasicHeader

private static Map<String, String> initialBasicHeader(String method, String path,
                                                          Map<String, String> headers, 
                                                          Map<String, String> querys,
                                                          Map<String, String> bodys,
                                                          List<String> signHeaderPrefixList,
                                                          String appKey, String appSecret)
            throws MalformedURLException {
        if (headers == null) {
            headers = new HashMap<String, String>();
        }

        headers.put(SystemHeader.X_CA_TIMESTAMP, String.valueOf(new Date().getTime()));
        //headers.put(SystemHeader.X_CA_X_CA_TIMESTAMPNONCE, UUID.randomUUID().toString());
        headers.put(SystemHeader.X_CA_KEY, appKey);
        headers.put(SystemHeader.X_CA_SIGNATURE,
                SignUtil.sign(appSecret, method, path, headers, querys, bodys, signHeaderPrefixList));

        return headers;
    }

sign

public static String sign(String secret, String method, String path, 
                                Map<String, String> headers, 
                                Map<String, String> querys, 
                                Map<String, String> bodys, 
                                List<String> signHeaderPrefixList) {
        try {
            Mac hmacSha256 = Mac.getInstance(Constants.HMAC_SHA256);
            byte[] keyBytes = secret.getBytes(Constants.ENCODING);
            hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, Constants.HMAC_SHA256));
                    hmacSha256.
            return new String(Base64.encodeBase64(
                    hmacSha256.doFinal(buildStringToSign(method, path, headers, querys, bodys, signHeaderPrefixList)
                            .getBytes(Constants.ENCODING))),
                    Constants.ENCODING);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

從而進行計算簽名
那么后端如何校驗簽名呢?
主要步驟如下:

  1. 得到請求方攜帶的API簽名。
  2. 將所有業(yè)務(wù)請求參數(shù)按字母先后順序排序。
  3. 參數(shù)名稱和參數(shù)值鏈接成一個字符串A。
  4. 在字符串A的首尾加上apiSecret接口密匙組成一個新字符串B。
  5. 對新字符串B進行HMAC_SHA256散列運算生成服務(wù)器端的API簽名,將客戶端的API簽名進行Base64解碼,然后開始驗證簽名。
  6. 如果服務(wù)器端生成的API簽名與客戶端請求的API簽名是一致的,則請求是可信的,否則就是不可信的。

API鑒權(quán)

先看看阿里云的RAM鑒權(quán)
阿里云使用權(quán)限來描述用戶、用戶組、角色對具體資源的訪問能力。
權(quán)限策略(Policy)
權(quán)限策略是用語法結(jié)構(gòu)描述的一組權(quán)限的集合,可以精確地描述被授權(quán)的資源集、操作集以及授權(quán)條件。
通過為RAM用戶、用戶組或RAM角色綁定權(quán)限策略,可以獲得權(quán)限策略中指定的訪問權(quán)限。

  • 基本元素

    • 效力(Effect):授權(quán)效力包括兩種:允許(Allow)和拒絕(Deny)。
    • 操作(Action):操作是指對具體資源的操作。
    • 資源(Resource):資源是指被授權(quán)的具體對象。
    • 限制條件(Condition): 限制條件是指授權(quán)生效的限制條件。
  • 權(quán)限策略結(jié)構(gòu)

    策略結(jié)構(gòu)

    Example:

  1. 通過指定的IP地址訪問阿里云
{
  "Statement": [
    {
      "Action": "ecs:*",
      "Effect": "Allow",
      "Resource": "*",
      "Condition": {
        "IpAddress": {
          "acs:SourceIp": "192.168.0.0/16"
        }
      }
    }
  ],
  "Version": "1"
}
  1. 在指定的時間段訪問阿里云。
{
  "Statement": [
    {
      "Action": "ecs:*",
      "Effect": "Allow",
      "Resource": "*",
      "Condition": {
          "DateLessThan": {
              "acs:CurrentTime": "2019-08-12T17:00:00+08:00"
          }
      }
    }
  ],
  "Version": "1"
}
  1. 列出并讀取一個存儲空間中的資源。
{
    "Version": "1",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "oss:ListObjects",
            "Resource": "acs:oss:*:*:myphotos"
        },
        {
            "Effect": "Allow",
            "Action": "oss:GetObject",
            "Resource": "acs:oss:*:*:myphotos/*"
        }
    ]
}

RAM鑒權(quán)
規(guī)則

  • 以主賬號身份訪問
  • 以RAM用戶身份訪問
  • 以RAM角色身份訪問
    主要講一下RAM角色身份訪問

檢查流程

訪問令牌
阿里云臨時安全令牌(Security Token Service,STS)是阿里云提供的一種臨時訪問權(quán)限管理服務(wù)。

接下來是,“阿里云讓你模仿,但沒有讓你超越
假如我們有一個菜單API如下:

  1. 身份類別


    身份類別

2.權(quán)限策略結(jié)構(gòu)

阿里云權(quán)限策略
demo權(quán)限策略結(jié)構(gòu)

json格式:
API1: http://localhost:8001/cargosmart/ssm2014/city/listCitys

{
  "Statement": [
    {
      "Action": "ssm2014:listCitys",
      "Effect": "Allow",
      "Resource": [
       "cs:ssm2014:123456:user/UserName",
       "cs:ssm2014:123456:group/groupName"  ,
       "cs:ssm2014:123456:role/roleName"],
      "Condition": {
          "DateLessThan": {
              "acs:CurrentTime": "2020-04-10T17:00:00+08:00"
          }
      }
    }
  ],
}

API2: http://localhost:8002/cargosmart/ssm2014/port/createPort

{
  "Statement": [
    {
      "Action": "ssm2014:createPort",
      "Effect": "Deny",
      "Resource": [
       "cs:ssm2014:23456:user/UserName",
       "cs:ssm2014:*:group/groupName"  ,
       "cs:ssm2014:23456:role/roleName"],
      "Condition": {
          "DateLessThan": {
              "acs:CurrentTime": "2020-04-10T17:00:00+08:00"
          }
      }
    }
  ],
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容