使用外部授权 API

更新时间:

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

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

授权

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

  1. 编写外部授权 API:在本地开发定义一个外部授权接口服务。

  2. 创建外部授权 API:在 API 网关控制台,配置对应的外部授权 API。

  3. 绑定 API:将创建好的外部授权 API 绑定一个 API,使其生效。

编写外部授权 API

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

  • 请求体

    {
    	"context" : {
      	"key": "value"
      }
    }

    字段说明:Request 中只有一个 context 字段,格式为 kv。这些参数来自于 client 的 request,需要在 API 网关控制台平台进行配置。

  • 响应体

    {
    	"success" : true/false,
      "principal" : {
      	"key" : "value"
      },
      "failResponseHeader" : {
      	"key" : "value"
      },
      "failResponseBody": jsonarray/jsonobject
      "failResponseStatus": ${httpcode}
    }

    字段说明

    • success:是否允许该请求转发到 real-server。

    • principal:如果允许转发到 real-server,可以将一些信息传递给 real-server,kv 格式。

      • 如果 real-server 是 HTTP 接口,则 principal 会放到 header 中。

      • 如果 real-server 是 SOFARPC 接口,则 principal 会放到 baggage 中。

    • failResponseHeader:如果不允许转发到 real-server,可以设置响应头返回给 client。

    • failResponseBody:如果不允许转发到 real-server,可以设置响应 body 给 client。

    • failResponseStatus:如果不允许转发到 real-server,可以设置响应 HTTP 状态码。

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

  • AuthRequest

    public class AuthRequest {
      private Map<String,String> context;
    }
  • AuthResponse

    public class AuthResponse {
      private boolean             success;
      private Map<String,String>  principal;
      private Map<String, String> failResponseHeader;
      private Object              failResponseBody;
      private int                 failResponseStatus;
    }
  • 接口示例

    @PostMapping("/testAuth")
    public AuthResponse testAuth(@RequestBody AuthRequest authRequest) {
        String sid = authRequest.getContext().get("sid");
        AuthResponse response = new AuthResponse();
        
        if (sid != null) {
         	Map<String, String> principal = new HashMap<>();
            principal.put("uid", sid + "_uid");
            response.setSuccess(true);
            response.setPrincipal(principal);
        } else {
        	response.setSuccess(false);
            
            Map<String, String> failResponseHeader = new HashMap<>();
    
            String queryKey = request.getContext().get("queryKey");
            if (queryKey.equalsIgnoreCase("q")) {
                failResponseHeader.put("header-to-client", "query");
            } else {
                failResponseHeader.put("header-to-client", "no-query");
            }
    
            response.setFailResponseHeader(failResponseHeader);
    
            Map<String, String> failResponseBody = new HashMap<>();
    
            String bodyKey = request.getContext().get("bodyKey");
            if (bodyKey.equalsIgnoreCase("b")) {
                failResponseBody.put("body-to-client", "b");
            } else {
                failResponseBody.put("body-to-client", "no-b");
            }
    
            response.setFailResponseBody(JSON.toJSONBytes(failResponseBody));
    
            response.setFailResponseStatus(401);
        	
        }
       
        return response;
    }

创建外部授权 API

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

  1. 进入 API 网关控制台页面,在左侧导航栏中选择 API 发布 > 外部授权 API

  2. 在外部授权 API 列表页,点击列表右上方的 创建外部授权 API

  3. 在新打开的页面中,选择或输入外部授权 API 相关信息:

    • 外部授权 API 名称:必填,用于识别该 API,支持英文字母、中文、数字、下划线(_)、连接符(-),32 个字符以内,以中文或字母开头。

    • 后端服务类型:目前仅支持 系统集群,即表示网关接收到前端请求后转发到真实业务系统的集群。

    • 协议类型:目前支持 HTTP 和 SOFARPC 协议。

      • HTTP 协议:

        • 请求路径:必填,API 请求所指向的资源 URL。以斜杠(/)开头,支持字母、数字、下划线(_)、连接符(-),200 字符以内。格式示例:/home/{id}

        • 方法:外部授权 API 必须使用 POST 方法,即将数据发送到服务器进行处理。

      • SOFARPC 协议:

        • 接口名称:必填,支持英文字母、数字、英文句号(.) 、冒号(:) 、@,以小写字母作为开头,格式示例: com.alipay.testapp.xxxx.ConfigFacade:1.0@DEFAULT

        • 服务标识:选填,支持指定服务的 uniqueId。

        • 方法名:支持英文字母和数字,以小写字母作为开头,格式示例: getUserID

    • 超时时间:必填,API 请求超时时间,单位为毫秒(ms)。

    • 缓存开关:即选择授权结果是否开启缓存。

      • 开启缓存后,如果 auth-server 返回 success,该结果会被缓存,缓存有效期内不会再次请求 auth-server。

      • 缓存时间不能超过 1 小时,不能低于 5s。

    • 路由策略:必选,表示当网关接收到请求后使用的路由策略。详见 创建路由规则

    • 系统集群:必选,选择提供该认证服务的后端集群。

    • 外部 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,最终的请求如下:

        {
        	"context" : {
          	"bodyKey" : "abc",
            "queryKey" : "q",
            "headerKey": "h"
          }
        }
  4. 确认 API 配置无误后,单击 创建 即可。

绑定 API

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

  1. API 发布 > 外部授权 API 页面,单击刚刚创建的外部授权 API 名称,进入其详情页。

  2. 外部授权 API 详情 > 绑定的 API 标签页下,单击 绑定 API

  3. 在弹出的窗口中,选择需要绑定的 API 后,单击 确定 即可。

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

说明

  • 一个业务 API 只能绑定一个外部授权 API。

  • 外部授权 API 只能绑定相同前端协议的业务 API。