阿里雲API網關(11)API的三種安全認證方式


網關指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 

網關控制台: https://apigateway.console.aliyun.com/?spm=5176.doc42740.2.2.Q4z5ws#/cn-hangzhou/apis/list

一、安全認證:無認證

在阿里雲的文檔【API 網關 > 開放 API 接入 API 網關 > 2. 前端配置】說明https://help.aliyun.com/document_detail/48805.html?spm=5176.doc48805.6.546.YPtFTr :

  

二、安全認證:阿里雲APP

三、安全認證:OpenConnect

1、獲取授權 api

  • 獲取授權API:向客戶端頒發Token的接口。配置這個API時您需要告知API網關,您Token對應的Key和解析Token使用的公鑰。

 

2、業務類接口

  • 業務類接口,是您實際的業務接口,比如獲取用戶息、進行某個操作等。配置這類API時,你需要告知API網關你請求中表示Token的參數名稱。請求到達API網關后,API網關自動認證這個請求是否合法。

四、附錄 - OpenID Connect 如何使用

OpenID Connect 是一套基於 OAuth 2.0 協議的輕量級規范,提供通過 API 進行身份交互的框架。較 OAuth 而言, OpenID Connect 方式除了認證請求之外,還標明請求的用戶身份。
API 網關依據 OpenConnect 的標准,對用戶請求進行 Appkey+Token 校驗,Token 由 API 提供者的系統頒發,網關頒發 Appkey,並負責 Appkey、Token 的真偽校驗。

實現原理

使用 OpenID Connect認證,將 API 分為 獲取授權 API 和 業務 API 兩類。
APi

API調用

  • 獲取授權API:向客戶端頒發Token的接口。配置這個API時您需要告知API網關,您Token對應的Key和解析Token使用的公鑰。
  • 業務類接口,是您實際的業務接口,比如獲取用戶息、進行某個操作等。配置這類API時,你需要告知API網關你請求中表示Token的參數名稱。請求到達API網關后,API網關自動認證這個請求是否合法。

認證方式

  1. 客戶端調用 獲取授權 API

    1. 客戶端使用您的 Appkey 簽名+用戶名/密碼 調用 獲取授權 API 獲取授權。
    2. API 網關收到請求后,先認證您的 Appkey,認證通過后,調用后端服務的賬號系統認證您傳遞的 用戶名/密碼。

    3. 后端服務認證通過后,返回 Token 給您,您可憑 Token 來調用 業務 API。

  2. 客戶端調用業務 API

    1. 客戶端使用 獲取授權 API 得到的 Token 和 簽名后的 Appkey 來調用 業務API。

    2. API 網關認證、解析 Token 的內容,並將 Token 中包含的用戶信息傳遞給后端。

    3. 在此階段的操作中,API 的提供者需要事先進行如下操作:

      1. 開放賬號系統,允許 API 網關對請求中 用戶名/密碼 進行驗證,並依據網關提供的加密方式,頒發 Token。詳細內容請參照下文 如何實現 AS 模塊。
      2. 在 API 網關定義 API。詳細內容參照下文 在 API 網關配置 API。
        注意:用戶名/密碼 是極為敏感的信息,在網絡中明文傳輸存在風險,建議在傳輸前對用戶名密碼再次加密,並使用 HTTPS 協議傳輸。

實現方案簡介

實現方案分為兩個重要的部分:

1. Authorization server(AS):認證服務器,負責生成 id_Token 並管理公鑰私鑰對。

這一步需要您自行實現。實現方法,請參照下文 在 API 網關配置 API。
u_p

參考上圖,流程簡述如下:

  1. Consumer(調用者)向API網關發送獲取 id_token 認證請求,比如:通過用戶名和密碼(U+P)的方式。
  2. API 網關透傳該請求到 AS。
  3. AS 向 Provider(服務提供方)發送認證用戶信息請求。
  4. Provider 響應認證結果,若失敗則直接響應錯誤信息。
  5. 認證結果成功,AS 生成 id_token,id_token 中包含了 User 信息(可擴展,也可包含其他必要信息)。
  6. API 網關將 AS 返回的 id_token 響應給 Consumer。

    說明:AS 不用必須是單獨部署的應用,完全可以集成在 Provider 中,在整個體系中擔任 id_token 生產者角色,所生成的 id_token 必須符合 OIDC(1.0版本)協議中的 規范

2. Resource server(RS):資源服務器,負責校驗 id_token,並解析出相應的信息。

此部分由網關來完成。因為 API 網關目前已經集成了 RS 功能,服務提供方只需要按照相應的加密規則生成 id_token 即可。
rs

參考上圖,流程簡述如下:

  1. Consumer 用帶有 id_token 的參數去請求 API 網關。
  2. API 網關會保存校驗所使用的公鑰,驗證並解析 id_token 獲取其中的 User 信息傳給 Provider,若驗證失敗則直接返回錯誤信息。
  3. Provider 處理請求並返回結果給 API 網關。
  4. API 網關透傳 Provider 響應的結果給 Consumer。

說明:RS 在整個體系中擔任 id_token 消費者角色,只有 id_token 校驗通過,才能將請求轉發給 Provider。

如何實現 AS 模塊

AS 中使用 OIDC 生成 id_token 的說明

  • id_token,也叫 ID Token,是在 OIDC 協議中定義的一種令牌,詳細內容參見 OpenID Connect Core 1.0
  • id_token 生成需要 KeyPair, keyId 與 Claims (有關Claims更多信息請訪問 ID_Token)。 

KeyId 說明

KeyId 必須保證唯一, 比如使用 UUID 生成的長度至少32位的隨機字符串, 可以全為數字或數字+字母。
參考示例(JAVA)

String keyId = UUID.randomUUID().toString().replaceAll("-", "");

String keyId = String.valueOf(UUID.randomUUID().getMostSignificantBits()) + String.valueOf(UUID.randomUUID().getMostSignificantBits());

KeyPair 說明

KeyPair 是一個基於 PKI 體系的非對稱算法的公私鑰組合, 每一對包括公鑰(publicKey)與私鑰(privateKey); 公鑰放置在 RS 中,在校驗(verify)時使用, 私鑰放置在 AS 中,在生成 id_token 時做數字簽名使用;
KeyPair 使用 RSA SHA256 加密算法, 為保證足夠安全其加密的位數為2048;
AS 中使用的 KeyPair 均為 JSON 格式的數據,一個示例如下:
publicKey:

{"kty":"RSA","kid":"67174182967979709913950471789226181721","alg":"ES256","n":"oH5WunqaqIopfOFBz9RfBVVIIcmk0WDJagAcROKFiLJScQ8N\_nrexgbCMlu-dSCUWq7XMnp1ZSqw-XBS2-XEy4W4l2Q7rx3qDWY0cP8pY83hqxTZ6-8GErJm\_0yOzR4WO4plIVVWt96-mxn3ZgK8kmaeotkS0zS0pYMb4EEOxFFnGFqjCThuO2pimF0imxiEWw5WCdREz1v8RW72WdEfLpTLJEOpP1FsFyG3OIDbTYOqowD1YQEf5Nk2TqN\_7pYrGRKsK3BPpw4s9aXHbGrpwsCRwYbKYbmeJst8MQ4AgcorE3NPmp-E6RxA5jLQ4axXrwC0T458LIVhypWhDqejUw","e":"AQAB"}

privateKey:

{"kty":"RSA","kid":"67174182967979709913950471789226181721","alg":"ES256","n":"oH5WunqaqIopfOFBz9RfBVVIIcmk0WDJagAcROKFiLJScQ8N\_nrexgbCMlu-dSCUWq7XMnp1ZSqw-XBS2-XEy4W4l2Q7rx3qDWY0cP8pY83hqxTZ6-8GErJm\_0yOzR4WO4plIVVWt96-mxn3ZgK8kmaeotkS0zS0pYMb4EEOxFFnGFqjCThuO2pimF0imxiEWw5WCdREz1v8RW72WdEfLpTLJEOpP1FsFyG3OIDbTYOqowD1YQEf5Nk2TqN\_7pYrGRKsK3BPpw4s9aXHbGrpwsCRwYbKYbmeJst8MQ4AgcorE3NPmp-E6RxA5jLQ4axXrwC0T458LIVhypWhDqejUw","e":"AQAB","d":"aQsHnLnOK-1xxghw2KP5JTZyJZsiwt-ENFqqJfPUzmlYSCNAV4T39chKpkch2utd7hRtSN6Zo4NTnY8EzGQQb9yvunaiEbWUkPyJ6kM3RdlkkGLvVtp0sRwPCZ2EAYBlsMad9jkyrtmdC0rtf9jerzt3LMLC7XWbnpC3WAl8rsRDR1CGs\_-u4sfZfttsaUbJDD9hD0q4NfLDCVOZoQ\_8wkZxyWDAQGCe6GcCbu6N81fTp2CSVbiBj7DST\_4x2NYUA2KG8vyZYcwviNTxQzk4iPfdN2YQz\_9aMTZmmhVUGlmTvAjE5ebBqcqKAS0NfhOQHg2uR46eBKBy\_OyVOLohsQ","p":"8Tdo3DCs-0t9JMtM0lYqPRP4wYJs37Rv6S-ygRui2MI\_hadTY9I2A199JMYw7Fjke\_wa3gqJLa98pbybdLWkrOxXbKEkwE4uc4-fuNjLbUTC5tqdM5-nXmpL887uREVYnk8FUzvWeXYTCNCb7OLw5l8yPJ1tR8aNcd0fJNDKh98","q":"qlRrGSTsZzBkDgDi1xlCoYvoM76cbmxrCUK-mc\_kBRHfMjlHosxFUnAbxqIBE4eAJEKVfIJLQrHFvIDjQb3kM9ylmwMCu9f8u9DHrT8J7LSDlLqDaXuiM2oiKtW3bAaBPuiR7sVMFcuB5baCebHU487YymJCBTfeCZtFdi6c4w0","dp":"gVCROKonsjiQCG-s6X4j-saAL016jJsw-7QEYE6uiMHqR\_6iJ\_uD1V8Vuec-RxaItyc6SBsh24oeqsNoG7Ndaw7w912UVDwVjwJKQFCJDjU0v4oniItosKcPvM8M0TDUB1qZojuMCWWRYsJjNSWcvAQA7JoBAd-h6I8AqT39tcU","dq":"BckMQjRg2zhnjZo2Gjw\_aSFJZ8iHo7CHCi98LdlD03BB9oC\_kCYEDMLGDr8d7j3h-llQnoQGbmN\_ZeGy1l7Oy3wpG9TEWQEDEpYK0jWb7rBK79hN8l1CqyBlvLK5oi-uYCaiHkwRQ4RACz9huyRxKLOz5VvlBixZnFXrzBHVPlk","qi":"M5NCVjSegf\_KP8kQLAudXUZi\_6X8T-owtsG\_gB9xYVGnCsbHW8gccRocOY1Xa0KMotTWJl1AskCu-TZhOJmrdeGpvkdulwmbIcnjA\_Fgflp4lAj4TCWmtRI6982hnC3XP2e-nf\_z2XsPNiuOactY7W042D\_cajyyX\_tBEJaGOXM"}

生成 KeyPair 參考示例(JAVA)

String keyId = UUID.randomUUID().toString().replaceAll("-", "");

RsaJsonWebKey jwk = RsaJwkGenerator.generateJwk(2048);

jwk.setKeyId(keyId);

jwk.setAlgorithm(AlgorithmIdentifiers.ECDSA\_USING\_P256\_CURVE\_AND\_SHA256);

String publicKey = jwk.toJson(JsonWebKey.OutputControlLevel.PUBLIC\_ONLY);

String privateKey = jwk.toJson(JsonWebKey.OutputControlLevel.INCLUDE\_PRIVATE);

生成 id_token 參考步驟

  1. 通過 OIDC 協議中定義的 Claims 屬性(aud, sub, exp, iat, iss)與其屬性值,生成 Claims(全稱 JwtClaims)

    示例代碼(JAVA)

JwtClaims claims = new JwtClaims();

claims.setGeneratedJwtId();

claims.setIssuedAtToNow();

//expire time

NumericDate date = NumericDate.now();

date.addSeconds(120);

claims.setExpirationTime(date);

claims.setNotBeforeMinutesInThePast(1);

claims.setSubject("YOUR_SUBJECT");

claims.setAudience("YOUR_AUDIENCE");

//添加自定義參數

claims.setClaim(key, value);

  1. 通過 keyId, Claims, privateKey 與使用的數字簽名算法 (RSA SHA256 )生成 JWS( Json Web Signature)

    示例代碼(JAVA)

JsonWebSignature jws = new JsonWebSignature();

jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA\_USING\_SHA256);

jws.setKeyIdHeaderValue(keyId);

ws.setPayload(claims.toJson());

PrivateKey privateKey = newRsaJsonWebKey(JsonUtil.parseJson(privateKeyText)).getPrivateKey();

jws.setKey(privateKey);

  1. 通過 JWS 獲取 id_token 值

    示例代碼(JAVA)

String idToken = jws.getCompactSerialization();

  1. 一個生成的 id_token 示例:

eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4NDgzNzI3NTU2OTI5MzI2NzAzMzA5OTA0MzUxMTg1ODE1NDg5In0.eyJ1c2VySWQiOiIzMzcwMTU0NDA2ODI1OTY4NjI3IiwidGFnTmFtZSI6ImNvbmFuVGVzdCIsImV4cCI6MTQ4MDU5Njg3OSwiYXVkIjoiQWxpX0FQSV9Vc2VyIiwianRpIjoiTm9DMFVVeW5xV0N0RUFEVjNoeEIydyIsImlhdCI6MTQ4MDU5MzI3OSwibmJmIjoxNDgwNTkzMjE5LCJzdWIiOiJ7ZGF0YU1hcD0ne3VzZXJJZD0zMzcwMTU0NDA2ODI1OTY4NjI3fScsIHN0YXR1c0NvZGU9JzAnLCBlcnJvcnM9J1tdJ30ifQ.V3rU2VCziSt6uTgdCktYRsIwkMEMsO_jUHNCCIW_Sp4qQ5ExjtwNt9h9mTGKFRujk2z1E0k36smWf9PbNGTZTWmSYN8rvcQqdsupcC6LU9r8jreA1Rw1CmmeWY4HsfBfeInr1wCFrEfZl6_QOtf3raKSK9AowhzEsnYRKAYuc297gmV8qlQdevAwU75qtg8j8ii3hZpJqTX67EteNCHZfhXn8wJjckl5sHz2xPPyMqj8CGRQ1wrZEHjUmNPw-unrUkt6neM0UrSqcjlrQ25L8PEL2TNs7nGVdl6iS7Nasbj8fsERMKcZbP2RFzOZfKJuaivD306cJIpQwxfS1u2bew

在 API 網關配置 API

    1. API 編輯功能中,基本信息欄目中安全認證增加 OpenID Connect 選項,這種方式同時也包括了 阿里雲APP 認證方式,也就是說只有被授權的 APP 才能調用這個 API。

      api

    2. 選擇 OpenID Connect 這種認證方式后,接下來要選擇 OpenID Connect 模式,有兩個選項:
      API-2

      1. 獲取授權 API:您用來換取 Token 的 API,比如:通過 U+P 換取 Token。
      2. 業務 API:也就是服務提供商提供服務的 API,調用者會把之前獲取到的 Token 作為入參進行調用。
        OpenID Connect 認證方式主要包含的就是以上這兩種 API,下文將分別說明這兩種API 是如何配置的。
    3. 獲取授權 API 還需要配置 KeyId 和公鑰,見下圖:
      pai-3

      KeyId:公鑰私鑰對 對應的一個唯一 Id,由 As 模塊負責生成的;示例:

88483727556929326703309904351185815489

    1. 公鑰:負責驗證和解析 Token,由 As 模塊負責生成的,示例:

{"kty":"RSA","kid":"88483727556929326703309904351185815489","alg":"ES256","n":"ie0IKvKLd7Y3izHcZemdDsVVXg5QtWtGF7XEkILnn66R2\_3a30DikqV409OVL7Hv0ElACgCaBLEgZeGHTcdLE1xxDTna8MMBnBNuMVghvFERCKh8uzpxlQsfcnFd5IFdJWj1x5Tscetrow6lA3h5zYx0rF5TkZzC4DclxgDmITRam0dsHBxr3uk9m9YYBz2mX0ehjY0px7vIo7hZH2J3gODEPorIZkk3x8GPdlaA4P9OFAO4au9-zcVQop9vLirxdwDedk2p-F9GP6UiQC9V2LTWqkVw\_oPBf9Rlh8Qdi19jA8SeCfzAxJZYlbOTK8dYAFAVEFsvXCFvdaxQefwWFw","e":"AQAB"}

    1. 設置完這些,后面的設置就和之前普通的 API 一樣了,在此就不贅述了。

      不管是創建 API 還是修改 API,所設置的 KeyId 和公鑰都是在 API 發布之后才會生效。

    2. 業務 API 需要配置 Token所對應的參數名稱。

      api-4

      1. 如上圖,Token 所對應的參數名稱:就是調用者調用 API 傳入 id_token 所使用的參數名,API 網關會識別這個參數值,校驗並解析。

      2. 然后在入參定義中,必須要定義一個對應參數,否則系統會出現錯誤提示,見下圖。api-5

      3. 設置自定義系統參數:業務 API在 定義 API 后端服務 標簽中會開放配置自定義系統參數,舉個例子,見下圖:
        api-6比如:AS 生成的 id_token 中包含了調用者的 userId,那么如果按照上圖這樣配置的話,就會把從調用者傳過來的 id_token 中解析出來的 userId 傳給服務提供方,配置方式和系統參數類似。
        除了以上3處,定義 API 其他配置和前文一樣,也就不再贅述了。

      以上就是 第三方賬號認證 OpenID Connect 在 API 網關配置的全部內容,供您參考!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM