閱讀485 返回首頁    go 人物


OpenID Connect認證__使用手冊(開放API)_API 網關-阿裏雲

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

實現原理:

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

API調用

客戶端調用“獲取授權 API ”

1.客戶端使用用戶的Appkey簽名+用戶名/密碼調用“獲取授權API”獲取授權;
2.API網關收到請求後,先認證用戶的Appkey,認證通過後,調用後端服務的賬號係統認證用戶傳遞的用戶名/密碼;
3.後端服務需要在認證通過後,返回“Token”給用戶,以便用戶使用Token來調用“業務 API ”。

客戶端調用業務API

1.客戶端使用“獲取授權 API ”返回的Token,用Appkey簽名後調用“業務API”;
2.API網關認證 Token 之後,解析 Token 內容,並將Token中包含的用戶信息傳遞給後端。

使用此方式API提供者需要準備

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

實現方案簡介

實現方案分為兩個重要的部分:
    1. Authorization server(AS):認證服務器,負責生成id_Token並管理公鑰私鑰對。需用戶自行實現,實現方法,請參照本文中的“如何實現AS模塊”。

u_p

AS在整個體係中擔任id_token生產者角色,所生成的id_token必須符合OIDC(1.0版本)協議中的規範(https://openid.net/specs/openid-connect-core-1_0.html)。AS不用必須是單獨部署的應用,完全可以集成在Provider中,隻要實現所需功能即可。
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。

    2. Resource server(RS):資源服務器,負責校驗id_token,並解析出相應的信息。Api網關目前已經集成了RS功能,服務提供方隻需要按照相應的加密規則生成id_token即可。此部分由網關來完成。

rs

RS在整個體係中擔任id_token消費者角色,隻有id_token校驗通過,才能將請求轉發給Provider。
1) Consumer用帶有id_token的參數去請求API網關。
2) Api網關會保存校驗所使用的公鑰,驗證並解析id_token獲取其中的User信息傳給Provider,若驗證失敗則直接返回錯誤信息。
3) Provider處理請求並返回結果給Api網關。
4) API網關透傳Provider響應的結果給Consumer。

如何實現AS模塊(AS中使用OIDC時的KeyId, KeyPair的生成與要求)

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

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

  1. String keyId = String.valueOf(UUID.randomUUID().getMostSignificantBits()) + String.valueOf(UUID.randomUUID().getMostSignificantBits());
2.KeyPair KeyPair是一個基於PKI體係的非對稱算法的公私鑰組合, 每一對包括公鑰(publicKey)與私鑰(privateKey); 公鑰放置在RS中,在校驗(verify)時使用, 私鑰放置在AS中,在生成id_token時做數字簽名使用;
KeyPair使用RSA SHA256加密算法, 為保證足夠安全其加密的位數為2048;
AS中使用的KeyPair均為JSON格式的數據,一個示例如下:
publicKey:
  1. {"kty":"RSA","kid":"67174182967979709913950471789226181721","alg":"ES256","n":"oH5WunqaqIopfOFBz9RfBVVIIcmk0WDJagAcROKFiLJScQ8N_nrexgbCMlu-dSCUWq7XMnp1ZSqw-XBS2-XEy4W4l2Q7rx3qDWY0cP8pY83hqxTZ6-8GErJm_0yOzR4WO4plIVVWt96-mxn3ZgK8kmaeotkS0zS0pYMb4EEOxFFnGFqjCThuO2pimF0imxiEWw5WCdREz1v8RW72WdEfLpTLJEOpP1FsFyG3OIDbTYOqowD1YQEf5Nk2TqN_7pYrGRKsK3BPpw4s9aXHbGrpwsCRwYbKYbmeJst8MQ4AgcorE3NPmp-E6RxA5jLQ4axXrwC0T458LIVhypWhDqejUw","e":"AQAB"}
privateKey:
  1. {"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)
  1. String keyId = UUID.randomUUID().toString().replaceAll("-", "");
  2. RsaJsonWebKey jwk = RsaJwkGenerator.generateJwk(2048);
  3. jwk.setKeyId(keyId);
  4. jwk.setAlgorithm(AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256);
  5. String publicKey = jwk.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);
  6. String privateKey = jwk.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
3.AS中使用OIDC 生成 id_token 說明
id_token,也叫ID Token,是在OIDC協議中定義的一種令牌,參見(https://openid.net/specs/openid-connect-core-1_0.html#IDToken)
id_token生成需要KeyPair, keyId與Claims(有關Claims更多信息請訪問 https://openid.net/specs/openid-connect-core-1_0.html#IDToken)
生成id_token參考步驟:
1). 通過OIDC協議中定義的Claims屬性(aud, sub, exp, iat, iss)與其屬性值,生成Claims(全稱JwtClaims)
示例代碼(JAVA)
  1. JwtClaims claims = new JwtClaims();
  2. claims.setGeneratedJwtId();
  3. claims.setIssuedAtToNow();
  4. //expire time
  5. NumericDate date = NumericDate.now();
  6. date.addSeconds(120);
  7. claims.setExpirationTime(date);
  8. claims.setNotBeforeMinutesInThePast(1);
  9. claims.setSubject("YOUR_SUBJECT");
  10. claims.setAudience("YOUR_AUDIENCE");
  11. //添加自定義參數
  12. claims.setClaim(key, value);
2). 通過keyId, Claims, privateKey與使用的數字簽名算法(RSA SHA256)生成JWS(Json Web Signature)
示例代碼(JAVA)
  1. JsonWebSignature jws = new JsonWebSignature();
  2. jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
  3. jws.setKeyIdHeaderValue(keyId);
  4. ws.setPayload(claims.toJson());
  5. PrivateKey privateKey = newRsaJsonWebKey(JsonUtil.parseJson(privateKeyText)).getPrivateKey();
  6. jws.setKey(privateKey);

3). 通過JWS獲取id_token值
示例代碼(JAVA) String idToken = jws.getCompactSerialization(); 一個生成的id_token示例:
  1. eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4NDgzNzI3NTU2OTI5MzI2NzAzMzA5OTA0MzUxMTg1ODE1NDg5In0.eyJ1c2VySWQiOiIzMzcwMTU0NDA2ODI1OTY4NjI3IiwidGFnTmFtZSI6ImNvbmFuVGVzdCIsImV4cCI6MTQ4MDU5Njg3OSwiYXVkIjoiQWxpX0FQSV9Vc2VyIiwianRpIjoiTm9DMFVVeW5xV0N0RUFEVjNoeEIydyIsImlhdCI6MTQ4MDU5MzI3OSwibmJmIjoxNDgwNTkzMjE5LCJzdWIiOiJ7ZGF0YU1hcD0ne3VzZXJJZD0zMzcwMTU0NDA2ODI1OTY4NjI3fScsIHN0YXR1c0NvZGU9JzAnLCBlcnJvcnM9J1tdJ30ifQ.V3rU2VCziSt6uTgdCktYRsIwkMEMsO_jUHNCCIW_Sp4qQ5ExjtwNt9h9mTGKFRujk2z1E0k36smWf9PbNGTZTWmSYN8rvcQqdsupcC6LU9r8jreA1Rw1CmmeWY4HsfBfeInr1wCFrEfZl6_QOtf3raKSK9AowhzEsnYRKAYuc297gmV8qlQdevAwU75qtg8j8ii3hZpJqTX67EteNCHZfhXn8wJjckl5sHz2xPPyMqj8CGRQ1wrZEHjUmNPw-unrUkt6neM0UrSqcjlrQ25L8PEL2TNs7nGVdl6iS7Nasbj8fsERMKcZbP2RFzOZfKJuaivD306cJIpQwxfS1u2bew

在Api網關配置API

1.Api編輯功能中,基本信息欄目中安全認證增加“OpenID Connect”選項,這種方式同時也包括了“阿裏雲APP”認證方式,也就是說隻有被授權的APP才能調用這個Api。api2.選擇“OpenID Connect”這種認證方式後,接下來要選擇“OpenID Connect模式”,有兩個選項:
API-2獲取授權API:用戶用來換取Token的Api,比如:通過U+P換取Token。
業務API:也就是服務提供商提供服務的Api,調用者會把之前獲取到的Token作為入參進行調用。
OpenID Connect認證方式主要包含的就是以上這兩種Api,下麵我們來分別說明這兩種Api是如何配置的。
3.獲取授權Api還需要配置KeyId和公鑰,見下圖:
pai-3KeyId:公鑰私鑰對 對應的一個唯一Id,由As模塊負責生成的;示例:

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

  1. {“kty”:”RSA”,”kid”:”88483727556929326703309904351185815489”,”alg”:”ES256”,”n”:”ie0IKvKLd7Y3izHcZemdDsVVXg5QtWtGF7XEkILnn66R2_3a30DikqV409OVL7Hv0ElACgCaBLEgZeGHTcdLE1xxDTna8MMBnBNuMVghvFERCKh8uzpxlQsfcnFd5IFdJWj1x5Tscetrow6lA3h5zYx0rF5TkZzC4DclxgDmITRam0dsHBxr3uk9m9YYBz2mX0ehjY0px7vIo7hZH2J3gODEPorIZkk3x8GPdlaA4P9OFAO4au9-zcVQop9vLirxdwDedk2p-F9GP6UiQC9V2LTWqkVw_oPBf9Rlh8Qdi19jA8SeCfzAxJZYlbOTK8dYAFAVEFsvXCFvdaxQefwWFw”,”e”:”AQAB”}

設置完這些,後麵的設置就和之前普通的Api一樣了,在此就不贅述了。

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

4.業務Api需要配置“Token所對應的參數名稱”,見下圖:
api-41) Token所對應的參數名稱:就是調用者調用Api傳入id_token所使用的參數名,Api網關會識別這個參數值,校驗並解析。
2) 然後在入參定義中,必須要定義一個對應參數,否則係統會出現錯誤提示。api-53) 設置自定義係統參數:業務Api在“定義Api後端服務”標簽中會開放配置自定義係統參數,舉個例子,見下圖:
api-6比如:AS生成的id_token中包含了調用者的userId,那麼如果按照上圖這樣配置的話,就會把從用戶傳過來的id_token中解析出來的userId傳給服務提供方,配置方式和係統參數類似。
除了以上3處,定義Api其他配置和以前一樣,也就不再贅述了。
以上就是 第三方賬號認證OpenID Connect 在Api網關配置的全部內容,供大家參考!

最後更新:2016-12-02 17:31:43

  上一篇:go 後端簽名密鑰說明文檔__使用手冊(開放API)_API 網關-阿裏雲
  下一篇:go 使用RAM管理API__使用手冊(開放API)_API 網關-阿裏雲