zoukankan      html  css  js  c++  java
  • OpenID Connect 是什么?

    一、OpenID Connect的概念

    1、OpenID Connect 是什么?

    OpenID Connect 是一套基于 OAuth 2.0 协议的轻量级规范,提供通过 API 进行身份交互的框架。

    OpenID Connect 使用简单的REST / JSON消息,开发者可以轻松集成。

    OpenID Connect 允许所有类型的客户,包括基于浏览器的JavaScript和本机移动应用程序。

    OpenID Connect 允许应用程序和网站的开发人员验证跨网站和应用程序的用户,却无需承担责任存储和管理用户密码。

    OpenID Connect 规范是开放的, 旨在鼓励一个开放的身份提供商生态系统。 

    OpenID Connect 简单,可靠,安全, 让开发者不需要存储和管理别人的密码,聚焦自己的功能提供,让用户的生活更容易,让网站注册逐渐减少!!!! 

    2、遵循的技术规范

    较 OAuth 而言, OpenID Connect 方式除了认证请求之外,还识别请求的用户身份。 

    OpenID Connect是OpenID的第三代技术。 

    OpenID Connect,外包所需的Web的内置TLS加密(也称为HTTPS和SSL)的基础设施,这些基础设备普遍地在客户端和服务器平台上实现。 

    OpenID Connect签名时使用标准JSON WEB TOKEN(JWT)数据结构。这让开发人员极大地更加容易实现OpenID Connect,在实践中有更好的互操作性。

    (身份验证) + OAuth 2.0 = OpenID Connect 

    3、规范演进

     

    二、OpenID Connect 的运行原理

    1、参与者

    2、运行机制

    3、典型场景

    3.1、服务网关用户授权验证

    在 Api服务网关场景中,Api网关(使用OpenID Connect)对 DevApp 发送的用户请求进行 Appkey+Token 校验

    • 服务提供者 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.2、两个重要的组件 as 和 rs

    Authorization server(AS):认证服务器,负责生成 id_Token 并管理公钥私钥对。

    Resource server(RS):资源服务器,负责校验 id_token,并解析出相应的信息。

    阿里云的API 网关目前已经集成了 RS 功能,服务提供方只需要按照相应的加密规则生成 id_token 即可。

     

    3.2、实现一个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

    4、开源实现

    三、OpenID Connect 的应用场景

    1、

    2、

     

  • 相关阅读:
    [hdu5136]Yue Fei's Battle 2014 亚洲区域赛广州赛区J题(dp)
    Codeforces Round #280 (Div. 2)E Vanya and Field(简单题)
    [hdu5113]Black And White2014北京赛区现场赛B题(搜索加剪枝)
    BestCoder Round #20 部分题解(A,B,C)(hdu5123,5124,5125)
    2014年亚洲区域赛北京赛区现场赛A,D,H,I,K题解(hdu5112,5115,5119,5220,5122)
    UVA 11754 Code Feat (枚举,中国剩余定理)
    Codeforces Round #277.5 (Div. 2) A,B,C,D,E,F题解
    UVA 11426 GCD
    UVALive 4119 Always an integer (差分数列,模拟)
    UVA 10253 Series-Parallel Networks (树形dp)
  • 原文地址:https://www.cnblogs.com/lexiaofei/p/7233230.html
Copyright © 2011-2022 走看看