網關指南: 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:向客戶端頒發Token的接口。配置這個API時您需要告知API網關,您Token對應的Key和解析Token使用的公鑰。
- 業務類接口,是您實際的業務接口,比如獲取用戶息、進行某個操作等。配置這類API時,你需要告知API網關你請求中表示Token的參數名稱。請求到達API網關后,API網關自動認證這個請求是否合法。
認證方式
-
客戶端調用 獲取授權 API
- 客戶端使用您的 Appkey 簽名+用戶名/密碼 調用 獲取授權 API 獲取授權。
-
API 網關收到請求后,先認證您的 Appkey,認證通過后,調用后端服務的賬號系統認證您傳遞的 用戶名/密碼。
-
后端服務認證通過后,返回 Token 給您,您可憑 Token 來調用 業務 API。
-
客戶端調用業務 API
-
客戶端使用 獲取授權 API 得到的 Token 和 簽名后的 Appkey 來調用 業務API。
-
API 網關認證、解析 Token 的內容,並將 Token 中包含的用戶信息傳遞給后端。
-
在此階段的操作中,API 的提供者需要事先進行如下操作:
- 開放賬號系統,允許 API 網關對請求中 用戶名/密碼 進行驗證,並依據網關提供的加密方式,頒發 Token。詳細內容請參照下文 如何實現 AS 模塊。
- 在 API 網關定義 API。詳細內容參照下文 在 API 網關配置 API。
注意:用戶名/密碼 是極為敏感的信息,在網絡中明文傳輸存在風險,建議在傳輸前對用戶名密碼再次加密,並使用 HTTPS 協議傳輸。
-
實現方案簡介
實現方案分為兩個重要的部分:
1. Authorization server(AS):認證服務器,負責生成 id_Token 並管理公鑰私鑰對。
這一步需要您自行實現。實現方法,請參照下文 在 API 網關配置 API。
參考上圖,流程簡述如下:
- Consumer(調用者)向API網關發送獲取 id_token 認證請求,比如:通過用戶名和密碼(U+P)的方式。
- API 網關透傳該請求到 AS。
- AS 向 Provider(服務提供方)發送認證用戶信息請求。
- Provider 響應認證結果,若失敗則直接響應錯誤信息。
- 認證結果成功,AS 生成 id_token,id_token 中包含了 User 信息(可擴展,也可包含其他必要信息)。
-
API 網關將 AS 返回的 id_token 響應給 Consumer。
說明:AS 不用必須是單獨部署的應用,完全可以集成在 Provider 中,在整個體系中擔任 id_token 生產者角色,所生成的 id_token 必須符合 OIDC(1.0版本)協議中的 規范。
2. Resource server(RS):資源服務器,負責校驗 id_token,並解析出相應的信息。
此部分由網關來完成。因為 API 網關目前已經集成了 RS 功能,服務提供方只需要按照相應的加密規則生成 id_token 即可。
參考上圖,流程簡述如下:
- Consumer 用帶有 id_token 的參數去請求 API 網關。
- API 網關會保存校驗所使用的公鑰,驗證並解析 id_token 獲取其中的 User 信息傳給 Provider,若驗證失敗則直接返回錯誤信息。
- Provider 處理請求並返回結果給 API 網關。
- 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 參考步驟
-
通過 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);
-
通過 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);
-
通過 JWS 獲取 id_token 值
示例代碼(JAVA)
String idToken = jws.getCompactSerialization();
-
一個生成的 id_token 示例:
eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4NDgzNzI3NTU2OTI5MzI2NzAzMzA5OTA0MzUxMTg1ODE1NDg5In0.eyJ1c2VySWQiOiIzMzcwMTU0NDA2ODI1OTY4NjI3IiwidGFnTmFtZSI6ImNvbmFuVGVzdCIsImV4cCI6MTQ4MDU5Njg3OSwiYXVkIjoiQWxpX0FQSV9Vc2VyIiwianRpIjoiTm9DMFVVeW5xV0N0RUFEVjNoeEIydyIsImlhdCI6MTQ4MDU5MzI3OSwibmJmIjoxNDgwNTkzMjE5LCJzdWIiOiJ7ZGF0YU1hcD0ne3VzZXJJZD0zMzcwMTU0NDA2ODI1OTY4NjI3fScsIHN0YXR1c0NvZGU9JzAnLCBlcnJvcnM9J1tdJ30ifQ.V3rU2VCziSt6uTgdCktYRsIwkMEMsO_jUHNCCIW_Sp4qQ5ExjtwNt9h9mTGKFRujk2z1E0k36smWf9PbNGTZTWmSYN8rvcQqdsupcC6LU9r8jreA1Rw1CmmeWY4HsfBfeInr1wCFrEfZl6_QOtf3raKSK9AowhzEsnYRKAYuc297gmV8qlQdevAwU75qtg8j8ii3hZpJqTX67EteNCHZfhXn8wJjckl5sHz2xPPyMqj8CGRQ1wrZEHjUmNPw-unrUkt6neM0UrSqcjlrQ25L8PEL2TNs7nGVdl6iS7Nasbj8fsERMKcZbP2RFzOZfKJuaivD306cJIpQwxfS1u2bew
在 API 網關配置 API
-
API 編輯功能中,基本信息欄目中安全認證增加 OpenID Connect 選項,這種方式同時也包括了 阿里雲APP 認證方式,也就是說只有被授權的 APP 才能調用這個 API。
-
選擇 OpenID Connect 這種認證方式后,接下來要選擇 OpenID Connect 模式,有兩個選項:
- 獲取授權 API:您用來換取 Token 的 API,比如:通過 U+P 換取 Token。
- 業務 API:也就是服務提供商提供服務的 API,調用者會把之前獲取到的 Token 作為入參進行調用。
OpenID Connect 認證方式主要包含的就是以上這兩種 API,下文將分別說明這兩種API 是如何配置的。
-
獲取授權 API 還需要配置 KeyId 和公鑰,見下圖:
KeyId:公鑰私鑰對 對應的一個唯一 Id,由 As 模塊負責生成的;示例:
88483727556929326703309904351185815489
- 公鑰:負責驗證和解析 Token,由 As 模塊負責生成的,示例:
{"kty":"RSA","kid":"88483727556929326703309904351185815489","alg":"ES256","n":"ie0IKvKLd7Y3izHcZemdDsVVXg5QtWtGF7XEkILnn66R2\_3a30DikqV409OVL7Hv0ElACgCaBLEgZeGHTcdLE1xxDTna8MMBnBNuMVghvFERCKh8uzpxlQsfcnFd5IFdJWj1x5Tscetrow6lA3h5zYx0rF5TkZzC4DclxgDmITRam0dsHBxr3uk9m9YYBz2mX0ehjY0px7vIo7hZH2J3gODEPorIZkk3x8GPdlaA4P9OFAO4au9-zcVQop9vLirxdwDedk2p-F9GP6UiQC9V2LTWqkVw\_oPBf9Rlh8Qdi19jA8SeCfzAxJZYlbOTK8dYAFAVEFsvXCFvdaxQefwWFw","e":"AQAB"}
-
設置完這些,后面的設置就和之前普通的 API 一樣了,在此就不贅述了。
不管是創建 API 還是修改 API,所設置的 KeyId 和公鑰都是在 API 發布之后才會生效。
-
業務 API 需要配置 Token所對應的參數名稱。
-
如上圖,Token 所對應的參數名稱:就是調用者調用 API 傳入 id_token 所使用的參數名,API 網關會識別這個參數值,校驗並解析。
-
然后在入參定義中,必須要定義一個對應參數,否則系統會出現錯誤提示,見下圖。
- 設置自定義系統參數:業務 API在 定義 API 后端服務 標簽中會開放配置自定義系統參數,舉個例子,見下圖:
比如:AS 生成的 id_token 中包含了調用者的 userId,那么如果按照上圖這樣配置的話,就會把從調用者傳過來的 id_token 中解析出來的 userId 傳給服務提供方,配置方式和系統參數類似。
除了以上3處,定義 API 其他配置和前文一樣,也就不再贅述了。
以上就是 第三方賬號認證 OpenID Connect 在 API 網關配置的全部內容,供您參考!
-