全部产品

使用外部授权 API

更新时间:2020-09-03 15:59:48

API 网关支持外部授权功能。通过该功能,用户可以在网关将请求转发给后端 server 之前,插入一个自定义的远程接口。网关会先将请求转发给这个自定义接口,该接口继而选择是否允许这个请求正常转发到后端 server。

如下图所示,步骤 2 即为调用自定义的远程接口。

授权

本文将引导您使用外部授权 API。完整的操作步骤如下:

  1. 编写外部授权 API:在本地开发定义一个外部授权接口服务。
  2. 创建外部授权 API:在 API 网关控制台,配置对应的外部授权 API。
  3. 绑定 API:将创建好的外部授权 API 绑定一个 API,使其生效。

编写外部授权 API

您需要在本地开发一个外部授权接口。当 API 需要验证授权关系时,会调用该外部授权接口进行授权校验。外部授权接口不限制协议类型,但会限制请求体和响应体。请求和响应均为 JSON 字符串,格式如下:

  • 请求体
    1. {
    2. "context" : {
    3. "key": "value"
    4. }
    5. }
    字段说明:Request 中只有一个 context 字段,格式为 kv。这些参数来自于 client 的 request,需要在 API 网关控制台平台进行配置。
  • 响应体
    1. {
    2. "success" : true/false,
    3. "principal" : {
    4. "key" : "value"
    5. },
    6. "failResponseHeader" : {
    7. "key" : "value"
    8. },
    9. "failResponseBody": jsonarray/jsonobject
    10. "failResponseStatus": ${httpcode}
    11. }
    字段说明
    • success:是否允许该请求转发到 real-server。
    • principal:如果允许转发到后端 server,可以将一些信息传递给 real-server,kv 格式。
      • 如果 real-server 是 HTTP 接口,则 principal 会放到 header 中。
      • 如果 real-server 是 SOFARPC 接口,则 principal 会放到 baggage 中。
    • failResponseHeader:如果不允许转发到后端 server,可以设置响应头返回给 client。
    • failResponseBody:如果不允许转发到后端 server,可以设置响应 body 给 client。
    • failResponseStatus:如果不允许转发到后端 server,可以设置响应 HTTP 状态码。

对应外部授权 API 的定义标准如下:

  • AuthRequest
    1. public class AuthRequest {
    2. private Map<String,String> context;
    3. }
  • AuthResponse
    1. public class AuthResponse {
    2. private boolean success;
    3. private Map<String,String> principal;
    4. private Map<String, String> failResponseHeader;
    5. private byte[] failResponseBody;
    6. private int failResponseStatus;
    7. }
  • 接口示例

    1. @PostMapping("/testAuth")
    2. public AuthResponse testAuth(@RequestBody AuthRequest authRequest) {
    3. String sid = authRequest.getContext().get("sid");
    4. AuthResponse response = new AuthResponse();
    5. if (sid != null) {
    6. Map<String, String> principal = new HashMap<>();
    7. principal.put("uid", sid + "_uid");
    8. response.setSuccess(true);
    9. response.setPrincipal(principal);
    10. } else {
    11. response.setSuccess(false);
    12. Map<String, String> failResponseHeader = new HashMap<>();
    13. String queryKey = request.getContext().get("queryKey");
    14. if (queryKey.equalsIgnoreCase("q")) {
    15. failResponseHeader.put("header-to-client", "query");
    16. } else {
    17. failResponseHeader.put("header-to-client", "no-query");
    18. }
    19. response.setFailResponseHeader(failResponseHeader);
    20. Map<String, String> failResponseBody = new HashMap<>();
    21. String bodyKey = request.getContext().get("bodyKey");
    22. if (bodyKey.equalsIgnoreCase("b")) {
    23. failResponseBody.put("body-to-client", "b");
    24. } else {
    25. failResponseBody.put("body-to-client", "no-b");
    26. }
    27. response.setFailResponseBody(JSON.toJSONBytes(failResponseBody));
    28. response.setFailResponseStatus(401);
    29. }
    30. return authResponse;
    31. }

创建外部授权 API

本地编写完外部授权接口后,您需要前往 API 网关的控制台上配置一个对应的外部授权 API。操作步骤如下:

  1. 进入 API 网关控制台页面,在左侧导航栏中选择 API 发布 > 外部授权 API
  2. 在外部授权 API 列表页,点击列表右上方的 创建外部授权 API
  3. 在新打开的页面中,选择或输入外部授权 API 相关信息:
    • 外部授权 API 名称:必填,用于识别该 API,支持英文字母、中文、数字、_、-,32 个字符以内,以中文或字母开头。
    • 后端服务类型:目前仅支持 系统集群,即表示网关接收到前端请求后转发到真实业务系统的集群。
    • 协议类型:支持多种协议。根据协议的不同,需要配置的信息也有所不同。
      • HTTP 协议:
        • 请求路径:必填,API 请求所指向的资源 URL。以斜杠 / 开头,支持字母、数字、 - 、_,200 字符以内。,格式示例:/home/{id}
        • 方法:外部授权 API 必须使用 POST 方法,即将数据发送到服务器进行处理。
      • SOFARPC 协议:(仅专有云)
        • 接口名称:必填,支持英文字母、数字、. 、: 、@,以小写字母作为开头,格式示例: com.alipay.testapp.facade.ConfigFacade:1.0@DEFAULT
        • 服务标识:选填,支持指定服务的 uniqueId。
        • 方法名:支持英文字母、数字组成,以小写字母作为开头,格式示例: getUserID
      • MRPC 协议:(仅专有云)
        • OperationType:必填,针对 mPaaS 移动应用设置的 API 服务标识,用于定位要访问的资源。
      • SOFAREST 协议:(仅专有云)
        • 方法:必选,外部授权 API 必须使用 POST 方法。
        • 接口名称:必填,支持英文字母、数字、. 、: 、@,以小写字母作为开头,格式示例: com.alipay.testapp.facade.ConfigFacade:1.0@DEFAULT
        • 服务标识:选填,支持指定服务的 uniqueId。
        • 请求路径:必填,API 请求所指向的资源 URL。以斜杠 / 开头,支持字母、数字、 - 、_,200 字符以内。,格式示例:/home/{id}
    • 超时时间:必填,API 请求超时时间,单位为毫秒(ms)。
    • 缓存开关:即选择授权结果是否开启缓存。
      • 开启缓存后,如果 auth-server 返回 success,该结果会被缓存,缓存有效期内不会再次请求 auth-server。
      • 缓存时间不能超过 1 小时,不能低于 5s。
    • 路由策略:必选,表示当网关接收到请求后使用的路由策略。详见 创建路由规则
    • 系统集群:必选,选择提供该认证服务的后端集群。
      授权api
    • 外部 API 参数:即 request.context 中的参数,可以从请求的 Header、Body、Cookie 和 Query 中提取。
      外部授权参数如上图配置所示,网关在调用 auth-server 时,会进行如下参数提取:
      • 从 Header 中取出 headerKey 的 value。
      • 从 Query 中取出 queryKey 的 value。
      • 从 Body 中取出 bodyKey 的 value。如 Body 为 {"bodyKey":"abc", "other": "xx"},则会取出 abc 这个 value。
        使用上述所有的 kv 构造一个 context,然后调用 auth-server,最终的请求如下:
        1. {
        2. "context" : {
        3. "bodyKey" : "abc",
        4. "queryKey" : "q",
        5. "headerKey": "h"
        6. }
        7. }
  4. 确认 API 配置无误后,点击 创建 即可。

绑定 API

外部授权 API 配置完成后,即可前往绑定 API 生效。操作步骤如下:

  1. API 发布 > 外部授权 API 页面,点击刚刚创建的外部授权 API 名称,进入其详情页。
  2. 外部授权 API 详情 > 绑定的 API 标签页下,点击 绑定 API
    绑定 API
  3. 在弹出的窗口中,选择需要绑定的 API 后,点击 确定 即可。

后续如需解绑,直接在 外部授权 API 详情 > 绑定的 API 中,选择需要解绑的 API,点击其右侧的 解除绑定 按钮,然后确定即可。