阅读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 网关-阿里云