• 阿里云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

    API调用

    • 获取授权API:向客户端颁发Token的接口。配置这个API时您需要告知API网关,您Token对应的Key和解析Token使用的公钥。
    • 业务类接口,是您实际的业务接口,比如获取用户息、进行某个操作等。配置这类API时,你需要告知API网关你请求中表示Token的参数名称。请求到达API网关后,API网关自动认证这个请求是否合法。

    认证方式

    1. 客户端调用 获取授权 API

      1. 客户端使用您的 Appkey 签名+用户名/密码 调用 获取授权 API 获取授权。
      2. API 网关收到请求后,先认证您的 Appkey,认证通过后,调用后端服务的账号系统认证您传递的 用户名/密码。

      3. 后端服务认证通过后,返回 Token 给您,您可凭 Token 来调用 业务 API。

    2. 客户端调用业务 API

      1. 客户端使用 获取授权 API 得到的 Token 和 签名后的 Appkey 来调用 业务API。

      2. API 网关认证、解析 Token 的内容,并将 Token 中包含的用户信息传递给后端。

      3. 在此阶段的操作中,API 的提供者需要事先进行如下操作:

        1. 开放账号系统,允许 API 网关对请求中 用户名/密码 进行验证,并依据网关提供的加密方式,颁发 Token。详细内容请参照下文 如何实现 AS 模块。
        2. 在 API 网关定义 API。详细内容参照下文 在 API 网关配置 API。
          注意:用户名/密码 是极为敏感的信息,在网络中明文传输存在风险,建议在传输前对用户名密码再次加密,并使用 HTTPS 协议传输。

    实现方案简介

    实现方案分为两个重要的部分:

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

    这一步需要您自行实现。实现方法,请参照下文 在 API 网关配置 API。
    u_p

    参考上图,流程简述如下:

    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。

      说明:AS 不用必须是单独部署的应用,完全可以集成在 Provider 中,在整个体系中担任 id_token 生产者角色,所生成的 id_token 必须符合 OIDC(1.0版本)协议中的 规范

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

    此部分由网关来完成。因为 API 网关目前已经集成了 RS 功能,服务提供方只需要按照相应的加密规则生成 id_token 即可。
    rs

    参考上图,流程简述如下:

    1. Consumer 用带有 id_token 的参数去请求 API 网关。
    2. API 网关会保存校验所使用的公钥,验证并解析 id_token 获取其中的 User 信息传给 Provider,若验证失败则直接返回错误信息。
    3. Provider 处理请求并返回结果给 API 网关。
    4. 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 参考步骤

    1. 通过 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);

    1. 通过 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);

    1. 通过 JWS 获取 id_token 值

      示例代码(JAVA)

    String idToken = jws.getCompactSerialization();

    1. 一个生成的 id_token 示例:

    eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4NDgzNzI3NTU2OTI5MzI2NzAzMzA5OTA0MzUxMTg1ODE1NDg5In0.eyJ1c2VySWQiOiIzMzcwMTU0NDA2ODI1OTY4NjI3IiwidGFnTmFtZSI6ImNvbmFuVGVzdCIsImV4cCI6MTQ4MDU5Njg3OSwiYXVkIjoiQWxpX0FQSV9Vc2VyIiwianRpIjoiTm9DMFVVeW5xV0N0RUFEVjNoeEIydyIsImlhdCI6MTQ4MDU5MzI3OSwibmJmIjoxNDgwNTkzMjE5LCJzdWIiOiJ7ZGF0YU1hcD0ne3VzZXJJZD0zMzcwMTU0NDA2ODI1OTY4NjI3fScsIHN0YXR1c0NvZGU9JzAnLCBlcnJvcnM9J1tdJ30ifQ.V3rU2VCziSt6uTgdCktYRsIwkMEMsO_jUHNCCIW_Sp4qQ5ExjtwNt9h9mTGKFRujk2z1E0k36smWf9PbNGTZTWmSYN8rvcQqdsupcC6LU9r8jreA1Rw1CmmeWY4HsfBfeInr1wCFrEfZl6_QOtf3raKSK9AowhzEsnYRKAYuc297gmV8qlQdevAwU75qtg8j8ii3hZpJqTX67EteNCHZfhXn8wJjckl5sHz2xPPyMqj8CGRQ1wrZEHjUmNPw-unrUkt6neM0UrSqcjlrQ25L8PEL2TNs7nGVdl6iS7Nasbj8fsERMKcZbP2RFzOZfKJuaivD306cJIpQwxfS1u2bew

    在 API 网关配置 API

      1. API 编辑功能中,基本信息栏目中安全认证增加 OpenID Connect 选项,这种方式同时也包括了 阿里云APP 认证方式,也就是说只有被授权的 APP 才能调用这个 API。

        api

      2. 选择 OpenID Connect 这种认证方式后,接下来要选择 OpenID Connect 模式,有两个选项:
        API-2

        1. 获取授权 API:您用来换取 Token 的 API,比如:通过 U+P 换取 Token。
        2. 业务 API:也就是服务提供商提供服务的 API,调用者会把之前获取到的 Token 作为入参进行调用。
          OpenID Connect 认证方式主要包含的就是以上这两种 API,下文将分别说明这两种API 是如何配置的。
      3. 获取授权 API 还需要配置 KeyId 和公钥,见下图:
        pai-3

        KeyId:公钥私钥对 对应的一个唯一 Id,由 As 模块负责生成的;示例:

    88483727556929326703309904351185815489

      1. 公钥:负责验证和解析 Token,由 As 模块负责生成的,示例:

    {"kty":"RSA","kid":"88483727556929326703309904351185815489","alg":"ES256","n":"ie0IKvKLd7Y3izHcZemdDsVVXg5QtWtGF7XEkILnn66R2\_3a30DikqV409OVL7Hv0ElACgCaBLEgZeGHTcdLE1xxDTna8MMBnBNuMVghvFERCKh8uzpxlQsfcnFd5IFdJWj1x5Tscetrow6lA3h5zYx0rF5TkZzC4DclxgDmITRam0dsHBxr3uk9m9YYBz2mX0ehjY0px7vIo7hZH2J3gODEPorIZkk3x8GPdlaA4P9OFAO4au9-zcVQop9vLirxdwDedk2p-F9GP6UiQC9V2LTWqkVw\_oPBf9Rlh8Qdi19jA8SeCfzAxJZYlbOTK8dYAFAVEFsvXCFvdaxQefwWFw","e":"AQAB"}

      1. 设置完这些,后面的设置就和之前普通的 API 一样了,在此就不赘述了。

        不管是创建 API 还是修改 API,所设置的 KeyId 和公钥都是在 API 发布之后才会生效。

      2. 业务 API 需要配置 Token所对应的参数名称。

        api-4

        1. 如上图,Token 所对应的参数名称:就是调用者调用 API 传入 id_token 所使用的参数名,API 网关会识别这个参数值,校验并解析。

        2. 然后在入参定义中,必须要定义一个对应参数,否则系统会出现错误提示,见下图。api-5

        3. 设置自定义系统参数:业务 API在 定义 API 后端服务 标签中会开放配置自定义系统参数,举个例子,见下图:
          api-6比如:AS 生成的 id_token 中包含了调用者的 userId,那么如果按照上图这样配置的话,就会把从调用者传过来的 id_token 中解析出来的 userId 传给服务提供方,配置方式和系统参数类似。
          除了以上3处,定义 API 其他配置和前文一样,也就不再赘述了。

        以上就是 第三方账号认证 OpenID Connect 在 API 网关配置的全部内容,供您参考!

  • 相关阅读:
    python基础学习之路No.2 数据类型
    练习题 --- 猜数字游戏
    python基础学习之路No.1
    python+selenium第一步
    Self-introduction
    oracle中的number类型
    简单选项卡切换(二)
    简单选项卡切换(一)
    简单焦点轮播(二)(图片可滚动)
    简单焦点轮播(一)
  • 原文地址:https://www.cnblogs.com/lexiaofei/p/7228265.html
Copyright © 2020-2023  润新知