OpenID Connect 是什么?
Posted 非淡泊无以明志,非宁静无以致远 - 长安快马
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
- DevApp 携带 Appkey签名+用户名/密码,访问 【获取授权 API】 获取授权。
- APIGW 收到请求后,先认证 Appkey,认证通过后,调用 SvcApp 的账号系统认证 用户名/密码。
- SvcApp 认证通过后,颁发Token给 DevApp,DevApp可凭 Token 来调用 业务 API。
- DevApp 调用业务 API
- 携带上一步 得到的 Token 和 签名后的 Appkey 来访问 【业务API】。
- 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);
- 公钥放置在 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)
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)
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 值
String idToken = jws.getCompactSerialization();
一个生成的 id_token 示例:
eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4NDgzNzI3NTU2OTI5MzI2NzAzMzA5OTA0MzUxMTg1ODE1NDg5In0.eyJ1c2VySWQiOiIzMzcwMTU0NDA2ODI1OTY4NjI3IiwidGFnTmFtZSI6ImNvbmFuVGVzdCIsImV4cCI6MTQ4MDU5Njg3OSwiYXVkIjoiQWxpX0FQSV9Vc2VyIiwianRpIjoiTm9DMFVVeW5xV0N0RUFEVjNoeEIydyIsImlhdCI6MTQ4MDU5MzI3OSwibmJmIjoxNDgwNTkzMjE5LCJzdWIiOiJ7ZGF0YU1hcD0ne3VzZXJJZD0zMzcwMTU0NDA2ODI1OTY4NjI3fScsIHN0YXR1c0NvZGU9JzAnLCBlcnJvcnM9J1tdJ30ifQ.V3rU2VCziSt6uTgdCktYRsIwkMEMsO_jUHNCCIW_Sp4qQ5ExjtwNt9h9mTGKFRujk2z1E0k36smWf9PbNGTZTWmSYN8rvcQqdsupcC6LU9r8jreA1Rw1CmmeWY4HsfBfeInr1wCFrEfZl6_QOtf3raKSK9AowhzEsnYRKAYuc297gmV8qlQdevAwU75qtg8j8ii3hZpJqTX67EteNCHZfhXn8wJjckl5sHz2xPPyMqj8CGRQ1wrZEHjUmNPw-unrUkt6neM0UrSqcjlrQ25L8PEL2TNs7nGVdl6iS7Nasbj8fsERMKcZbP2RFzOZfKJuaivD306cJIpQwxfS1u2bew
4、开源实现
三、OpenID Connect 的应用场景
1、
2、
以上是关于OpenID Connect 是什么?的主要内容,如果未能解决你的问题,请参考以下文章
我的世界联机:出现了这串字母 Java.net.connect.exception:connec
什么 OpenID Connect 授权流程来验证移动应用程序用户?