阿里云API网关(11)API的三种安全认证方式
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl
网关控制台: https://apigateway.console.aliyun.com/?spm=5176.doc42740.2.2.Q4z5ws#/cn-hangzhou/apis/list
一、安全认证:无认证
在阿里云的文档【API 网关 > 开放 API 接入 API 网关 > 2. 前端配置】说明:https://help.aliyun.com/document_detail/48805.html?spm=5176.doc48805.6.546.YPtFTr :
二、安全认证:阿里云APP
三、安全认证:OpenConnect
1、获取授权 api
- 获取授权API:向客户端颁发Token的接口。配置这个API时您需要告知API网关,您Token对应的Key和解析Token使用的公钥。
2、业务类接口
- 业务类接口,是您实际的业务接口,比如获取用户息、进行某个操作等。配置这类API时,你需要告知API网关你请求中表示Token的参数名称。请求到达API网关后,API网关自动认证这个请求是否合法。
四、附录 - OpenID Connect 如何使用
OpenID Connect 是一套基于 OAuth 2.0 协议的轻量级规范,提供通过 API 进行身份交互的框架。较 OAuth 而言, OpenID Connect 方式除了认证请求之外,还标明请求的用户身份。
API 网关依据 OpenConnect 的标准,对用户请求进行 Appkey+Token 校验,Token 由 API 提供者的系统颁发,网关颁发 Appkey,并负责 Appkey、Token 的真伪校验。
实现原理
使用 OpenID Connect认证,将 API 分为 获取授权 API 和 业务 API 两类。
- 获取授权API:向客户端颁发Token的接口。配置这个API时您需要告知API网关,您Token对应的Key和解析Token使用的公钥。
- 业务类接口,是您实际的业务接口,比如获取用户息、进行某个操作等。配置这类API时,你需要告知API网关你请求中表示Token的参数名称。请求到达API网关后,API网关自动认证这个请求是否合法。
认证方式
客户端调用 获取授权 API
- 客户端使用您的 Appkey 签名+用户名/密码 调用 获取授权 API 获取授权。
API 网关收到请求后,先认证您的 Appkey,认证通过后,调用后端服务的账号系统认证您传递的 用户名/密码。
后端服务认证通过后,返回 Token 给您,您可凭 Token 来调用 业务 API。
客户端调用业务 API
客户端使用 获取授权 API 得到的 Token 和 签名后的 Appkey 来调用 业务API。
API 网关认证、解析 Token 的内容,并将 Token 中包含的用户信息传递给后端。
在此阶段的操作中,API 的提供者需要事先进行如下操作:
- 开放账号系统,允许 API 网关对请求中 用户名/密码 进行验证,并依据网关提供的加密方式,颁发 Token。详细内容请参照下文 如何实现 AS 模块。
- 在 API 网关定义 API。详细内容参照下文 在 API 网关配置 API。
注意:用户名/密码 是极为敏感的信息,在网络中明文传输存在风险,建议在传输前对用户名密码再次加密,并使用 HTTPS 协议传输。
实现方案简介
实现方案分为两个重要的部分:
1. Authorization server(AS):认证服务器,负责生成 id_Token 并管理公钥私钥对。
这一步需要您自行实现。实现方法,请参照下文 在 API 网关配置 API。
参考上图,流程简述如下:
- Consumer(调用者)向API网关发送获取 id_token 认证请求,比如:通过用户名和密码(U+P)的方式。
- API 网关透传该请求到 AS。
- AS 向 Provider(服务提供方)发送认证用户信息请求。
- Provider 响应认证结果,若失败则直接响应错误信息。
- 认证结果成功,AS 生成 id_token,id_token 中包含了 User 信息(可扩展,也可包含其他必要信息)。
API 网关将 AS 返回的 id_token 响应给 Consumer。
说明:AS 不用必须是单独部署的应用,完全可以集成在 Provider 中,在整个体系中担任 id_token 生产者角色,所生成的 id_token 必须符合 OIDC(1.0版本)协议中的 规范。
2. Resource server(RS):资源服务器,负责校验 id_token,并解析出相应的信息。
此部分由网关来完成。因为 API 网关目前已经集成了 RS 功能,服务提供方只需要按照相应的加密规则生成 id_token 即可。
参考上图,流程简述如下:
- Consumer 用带有 id_token 的参数去请求 API 网关。
- API 网关会保存校验所使用的公钥,验证并解析 id_token 获取其中的 User 信息传给 Provider,若验证失败则直接返回错误信息。
- Provider 处理请求并返回结果给 API 网关。
- API 网关透传 Provider 响应的结果给 Consumer。
说明:RS 在整个体系中担任 id_token 消费者角色,只有 id_token 校验通过,才能将请求转发给 Provider。
如何实现 AS 模块
AS 中使用 OIDC 生成 id_token 的说明
- id_token,也叫 ID Token,是在 OIDC 协议中定义的一种令牌,详细内容参见 OpenID Connect Core 1.0。
- id_token 生成需要 KeyPair, keyId 与 Claims (有关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)
示例代码(JAVA)
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)
示例代码(JAVA)
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 值
示例代码(JAVA)
String idToken = jws.getCompactSerialization();
一个生成的 id_token 示例:
eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4NDgzNzI3NTU2OTI5MzI2NzAzMzA5OTA0MzUxMTg1ODE1NDg5In0.eyJ1c2VySWQiOiIzMzcwMTU0NDA2ODI1OTY4NjI3IiwidGFnTmFtZSI6ImNvbmFuVGVzdCIsImV4cCI6MTQ4MDU5Njg3OSwiYXVkIjoiQWxpX0FQSV9Vc2VyIiwianRpIjoiTm9DMFVVeW5xV0N0RUFEVjNoeEIydyIsImlhdCI6MTQ4MDU5MzI3OSwibmJmIjoxNDgwNTkzMjE5LCJzdWIiOiJ7ZGF0YU1hcD0ne3VzZXJJZD0zMzcwMTU0NDA2ODI1OTY4NjI3fScsIHN0YXR1c0NvZGU9JzAnLCBlcnJvcnM9J1tdJ30ifQ.V3rU2VCziSt6uTgdCktYRsIwkMEMsO_jUHNCCIW_Sp4qQ5ExjtwNt9h9mTGKFRujk2z1E0k36smWf9PbNGTZTWmSYN8rvcQqdsupcC6LU9r8jreA1Rw1CmmeWY4HsfBfeInr1wCFrEfZl6_QOtf3raKSK9AowhzEsnYRKAYuc297gmV8qlQdevAwU75qtg8j8ii3hZpJqTX67EteNCHZfhXn8wJjckl5sHz2xPPyMqj8CGRQ1wrZEHjUmNPw-unrUkt6neM0UrSqcjlrQ25L8PEL2TNs7nGVdl6iS7Nasbj8fsERMKcZbP2RFzOZfKJuaivD306cJIpQwxfS1u2bew
在 API 网关配置 API
API 编辑功能中,基本信息栏目中安全认证增加 OpenID Connect 选项,这种方式同时也包括了 阿里云APP 认证方式,也就是说只有被授权的 APP 才能调用这个 API。
选择 OpenID Connect 这种认证方式后,接下来要选择 OpenID Connect 模式,有两个选项:
- 获取授权 API:您用来换取 Token 的 API,比如:通过 U+P 换取 Token。
- 业务 API:也就是服务提供商提供服务的 API,调用者会把之前获取到的 Token 作为入参进行调用。
OpenID Connect 认证方式主要包含的就是以上这两种 API,下文将分别说明这两种API 是如何配置的。
获取授权 API 还需要配置 KeyId 和公钥,见下图:
KeyId:公钥私钥对 对应的一个唯一 Id,由 As 模块负责生成的;示例:
88483727556929326703309904351185815489
- 公钥:负责验证和解析 Token,由 As 模块负责生成的,示例:
{"kty":"RSA","kid":"88483727556929326703309904351185815489","alg":"ES256","n":"ie0IKvKLd7Y3izHcZemdDsVVXg5QtWtGF7XEkILnn66R2\_3a30DikqV409OVL7Hv0ElACgCaBLEgZeGHTcdLE1xxDTna8MMBnBNuMVghvFERCKh8uzpxlQsfcnFd5IFdJWj1x5Tscetrow6lA3h5zYx0rF5TkZzC4DclxgDmITRam0dsHBxr3uk9m9YYBz2mX0ehjY0px7vIo7hZH2J3gODEPorIZkk3x8GPdlaA4P9OFAO4au9-zcVQop9vLirxdwDedk2p-F9GP6UiQC9V2LTWqkVw\_oPBf9Rlh8Qdi19jA8SeCfzAxJZYlbOTK8dYAFAVEFsvXCFvdaxQefwWFw","e":"AQAB"}
设置完这些,后面的设置就和之前普通的 API 一样了,在此就不赘述了。
不管是创建 API 还是修改 API,所设置的 KeyId 和公钥都是在 API 发布之后才会生效。
业务 API 需要配置 Token所对应的参数名称。
如上图,Token 所对应的参数名称:就是调用者调用 API 传入 id_token 所使用的参数名,API 网关会识别这个参数值,校验并解析。
然后在入参定义中,必须要定义一个对应参数,否则系统会出现错误提示,见下图。
- 设置自定义系统参数:业务 API在 定义 API 后端服务 标签中会开放配置自定义系统参数,举个例子,见下图:
比如:AS 生成的 id_token 中包含了调用者的 userId,那么如果按照上图这样配置的话,就会把从调用者传过来的 id_token 中解析出来的 userId 传给服务提供方,配置方式和系统参数类似。
除了以上3处,定义 API 其他配置和前文一样,也就不再赘述了。
以上就是 第三方账号认证 OpenID Connect 在 API 网关配置的全部内容,供您参考!
阿里云API网关(11)API的三种安全认证方式相关推荐
- 使用阿里云短信服务API实现短信验证码以及短信服务通知
使用阿里云短信服务API实现短信验证码以及短信服务通知 前言 一 .短信调用简要说明 二 .官方不带签名原生态测试demo 调用结果如下 三 .以上为不带模板和签名的API调用结果 下面加入签名和模板 ...
- ML之API:国内外各大人工智能平台(百度云/华为云/阿里云/Face++等)及其API的简介、使用方法之详细攻略
ML之API:国内外各大人工智能平台(百度云/华为云/阿里云/Face++等)及其API的简介.使用方法之详细攻略 目录 一.百度云api 1.api之CV 二.旷视科技(face++)api 1.a ...
- 使用阿里云短信验证码API发送短信验证码(配置,获取短信验证码,注册,登录,密码重置)
获取阿里云短信验证码需要的配置信息. 如果是新用户,可以免费领取3个月,老用户的话就只能购买了,但是也不贵. 申请短信签名 申请短信模板 编写发送短信验证码的工具类 代码中我已经进行了详细的注释,也写 ...
- 阿里云人脸比对API封装
这是根据封装是根据阿里云官方给的Demo进行修改的,当时是因为编写微信小程序云函数需要使用到阿里云人脸比对接口,才对其进行封装的. 记录下来,方便下次使用. 复制下来可以直接使用. 用到的依赖如下,使 ...
- 什么是API网关, API 网关的作用
一.什么是API Gateway 我们知道在微服务架构中,大型服务都被拆分成了独立的微服务,每个微服务通常会以RESTFUL API的形式对外提供服务.但是在UI方面,我们可能需要在一个页面上显示来自 ...
- API 网关 (API Gataway)
API 网关 (API Gataway) API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各 ...
- 阿里云IOT网关BL110应用之28:实现三菱 PLC FX3U 接入阿里云平台
COM口采集三菱 PLC FX3U 的配置 工业智能网关一共有四个COM 接口, 4个COM口的配置内容一样,COM1固定为RS232,COM2.COM3和COM4是RS232/RS485可选串口(默 ...
- api网关 网页服务器,api网关 定义后端服务器
api网关 定义后端服务器 内容精选 换一换 通过以下方法确保API网关调用后端服务器的安全:为API绑定签名密钥.在绑定签名密钥后,API网关到后端服务的请求增加签名信息,后端服务收到请求后计算签名 ...
- 数据库诞生40年,阿里云AWS用技术推动第三次变革
本文讲的是数据库诞生40年,阿里云AWS用技术推动第三次变革,数据库诞生于上世纪50/60年代.1961年美国通用公司研发第一个数据库系统DBMS诞生.1976年霍尼韦尔公司(Honeywell)开发 ...
最新文章
- input must have last dimension = k = 3 but is 2 for 'TopKV2_这种错误是怎么产生的
- web app中常用插件(zepto--用法类似于jquery、利用nodejs定制zepto)
- js获取当前日期方法
- chrom浏览器-F2使用方法一
- C#LeetCode刷题之#860-柠檬水找零(Lemonade Change)
- 技巧:macOS 在 Finder(访达)中查看文件夹大小
- Laravel 项目使用 Carbon 人性化显示文章发表时间
- C++11 pair的使用
- Java中涉及线程和并发相关的内容
- spring boot企业合同管理系统 毕业设计源码161456
- 数电笔记:触发器的基础知识
- 带键盘的java模拟器_虚拟键盘实现!JAVA模拟器PSPKVM v0.3.2推出
- ubuntu企业微信解决无法查看、发送图片
- 127_不同国家的手机号,除去国家代码后,有可能相同吗?
- 分支语句和循环语句[一]【详解】
- STGCN的源码分析
- 【ts】typeScript高阶:any和unknown
- Python基础学习之”基础语法5
- php 模板编译类,一个简单的模板类--编译型的(simplet类增强后)
- 详记Android打开相机拍照流程