使用外部授权 API
API 网关支持外部授权功能。通过该功能,用户可以在网关将请求转发给 real-server 之前,插入一个自定义的远程接口。网关会先将请求转发给这个自定义接口,该接口继而选择是否允许这个请求正常转发到 real-server。
如下图所示,步骤 2 即为调用自定义的远程接口。
本文将引导您使用外部授权 API。完整的操作步骤如下:
编写外部授权 API:在本地开发定义一个外部授权接口服务。
创建外部授权 API:在 API 网关控制台,配置对应的外部授权 API。
绑定 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。操作步骤如下:
进入 API 网关控制台页面,在左侧导航栏中选择 API 发布 > 外部授权 API。
在外部授权 API 列表页,点击列表右上方的 创建外部授权 API。
在新打开的页面中,选择或输入外部授权 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" } }
确认 API 配置无误后,单击 创建 即可。
绑定 API
外部授权 API 配置完成后,即可前往绑定 API 生效。操作步骤如下:
在 API 发布 > 外部授权 API 页面,单击刚刚创建的外部授权 API 名称,进入其详情页。
在 外部授权 API 详情 > 绑定的 API 标签页下,单击 绑定 API。
在弹出的窗口中,选择需要绑定的 API 后,单击 确定 即可。
后续如需解绑,直接在 外部授权 API 详情 > 绑定的 API 中,选择需要解绑的 API,单击其右侧的 解除绑定 按钮,然后确定即可。
一个业务 API 只能绑定一个外部授权 API。
外部授权 API 只能绑定相同前端协议的业务 API。