OpenID Connect 是什麼?

1、OpenID Connect的概念

一、OpenID Connect 是什麼?

OpenID Connect 是一套基於 OAuth 2.0 協議的輕量級規範,提供經過 API 進行身份交互的框架。html

OpenID Connect 使用簡單的REST / JSON消息,開發者能夠輕鬆集成。算法

OpenID Connect 容許全部類型的客戶,包括基於瀏覽器的JavaScript和本機移動應用程序。瀏覽器

OpenID Connect 容許應用程序和網站的開發人員驗證跨網站和應用程序的用戶,卻無需承擔責任存儲和管理用戶密碼。安全

OpenID Connect 規範是開放的, 旨在鼓勵一個開放的身份提供商生態系統。 服務器

OpenID Connect 簡單,可靠,安全, 讓開發者不須要存儲和管理別人的密碼,聚焦本身的功能提供,讓用戶的生活更容易,讓網站註冊逐漸減小!!!! 

二、遵循的技術規範

較 OAuth 而言, OpenID Connect 方式除了認證請求以外,還識別請求的用戶身份。 數據結構

OpenID Connect是OpenID的第三代技術。 框架

OpenID Connect,外包所需的Web的內置TLS加密(也稱爲HTTPS和SSL)的基礎設施,這些基礎設備廣泛地在客戶端和服務器平臺上實現。 dom

OpenID Connect簽名時使用標準JSON WEB TOKEN(JWT)數據結構。這讓開發人員極大地更加容易實現OpenID Connect,在實踐中有更好的互操做性。網站

(身份驗證) + OAuth 2.0 = OpenID Connect 

三、規範演進

 

2、OpenID Connect 的運行原理

一、參與者

二、運行機制

三、典型場景

3.一、服務網關用戶受權驗證

在 Api服務網關場景中,Api網關(使用OpenID Connect)對 DevApp 發送的用戶請求進行 Appkey+Token 校驗ui

  • 服務提供者 SvcApp 負責頒發Token ,
  • Appkey 由網關頒發 ,網關負責 Appkey、Token 的真僞校驗。

Api服務網關,使用 OpenID Connect認證,將 服務提供者的API 分爲 獲取受權 API 和 業務 API 兩類。

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

 

  • DevApp 調用 獲取受權 API 
  1. DevApp 攜帶 Appkey簽名+用戶名/密碼,訪問 【獲取受權 API】 獲取受權。
  2. APIGW 收到請求後,先認證 Appkey,認證經過後,調用 SvcApp 的帳號系統認證 用戶名/密碼。
  3. SvcApp 認證經過後,頒發Token給 DevApp,DevApp可憑 Token 來調用 業務 API。 
  • DevApp 調用業務 API 
  1. 攜帶上一步 獲得的 Token 和 簽名後的 Appkey 來訪問 【業務API】。
  2. APIGW 認證、解析 Token,並將 Token 中包含的用戶信息,傳遞給 SvcApp。 

3.二、兩個重要的組件 as 和 rs

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

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

阿里雲的API 網關目前已經集成了 RS 功能,服務提供方只須要按照相應的加密規則生成 id_token 便可。

 

 

3.二、實現一個as

id_token( ID Token),是在 OIDC 協議中定義的一種令牌,id_token 生成須要 KeyPair, keyId 與 Claims

id_token: 詳細內容參見 OpenID Connect Core 1.0

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);

  1. 公鑰放置在 RS 中,在校驗(verify)時使用,
  2. 私鑰放置在 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)

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)

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 值

String idToken = jws.getCompactSerialization();

一個生成的 id_token 示例:

eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4NDgzNzI3NTU2OTI5MzI2NzAzMzA5OTA0MzUxMTg1ODE1NDg5In0.eyJ1c2VySWQiOiIzMzcwMTU0NDA2ODI1OTY4NjI3IiwidGFnTmFtZSI6ImNvbmFuVGVzdCIsImV4cCI6MTQ4MDU5Njg3OSwiYXVkIjoiQWxpX0FQSV9Vc2VyIiwianRpIjoiTm9DMFVVeW5xV0N0RUFEVjNoeEIydyIsImlhdCI6MTQ4MDU5MzI3OSwibmJmIjoxNDgwNTkzMjE5LCJzdWIiOiJ7ZGF0YU1hcD0ne3VzZXJJZD0zMzcwMTU0NDA2ODI1OTY4NjI3fScsIHN0YXR1c0NvZGU9JzAnLCBlcnJvcnM9J1tdJ30ifQ.V3rU2VCziSt6uTgdCktYRsIwkMEMsO_jUHNCCIW_Sp4qQ5ExjtwNt9h9mTGKFRujk2z1E0k36smWf9PbNGTZTWmSYN8rvcQqdsupcC6LU9r8jreA1Rw1CmmeWY4HsfBfeInr1wCFrEfZl6_QOtf3raKSK9AowhzEsnYRKAYuc297gmV8qlQdevAwU75qtg8j8ii3hZpJqTX67EteNCHZfhXn8wJjckl5sHz2xPPyMqj8CGRQ1wrZEHjUmNPw-unrUkt6neM0UrSqcjlrQ25L8PEL2TNs7nGVdl6iS7Nasbj8fsERMKcZbP2RFzOZfKJuaivD306cJIpQwxfS1u2bew

 

四、開源實現

 

 

3、OpenID Connect 的應用場景

一、

二、

相關文章
相關標籤/搜索