如何在请求前在 Swagger 中计算 AWS 签名 V4
How to calculate AWS signature V4 in Swagger before request
对于我们的 AWS API 端点,我们使用 AWS_IAM 授权并希望从 Swagger UI 进行调用。
要成功调用,必须有 2 headers 'Authorization' 和 'x-amz-date'。为了形成 'Authorization',我们使用 following steps from aws doc。
我们必须在每次调用时更改 'x-amz-date' 才能通过授权。
问题是:如何在 Swagger 中编写脚本来签署请求,每次 在 请求发送到 aws 之前 运行?
(我们知道如何在加载 Swagger 页面之前指定一次 headers,但是这个过程应该在每次 调用之前 re-run 。
提前致谢。
在 swagger-js 中有 built-in 支持添加 requestInterceptor
来做到这一点。 swagger-ui 项目在后台使用 swagger-js。
像这样简单地创建一个请求拦截器:
requestInterceptor: {
apply: function (request) {
// modify the request object here
return request;
}
}
并在创建时将其应用于您的 swagger 实例:
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
requestInterceptor: requestInterceptor,
这里可以在request
object中设置headers(注意,这不是标准javascripthttp请求 object,检查它以获取详细信息)。但是您在这里确实可以访问所有 headers,因此您可以根据需要计算和注入它们。
您可以很容易地将 AWS SDK 中的签名 monkeypatch 签名到 SwaggerJS(以及 SwaggerUI)中。参见 here
我有一个稍微修改过的 SwaggerUI here。给定一些 AWS 凭证和一个 API ID,它将拉下 Swagger 定义,将其显示在 SwaggerUI 中,然后您可以使用 sigv4 调用 API。
Authorizer 实现如下所示:
var AWSSigv4RequestSigner = function(credentialProvider, aws) {
this.name = "sigv4";
this.aws = aws;
this.credentialProvider = credentialProvider;
};
AWSSigv4RequestSigner.prototype.apply = function(options, authorizations) {
var serviceName = "execute-api";
//If we are loading the definition itself, then we need to sign for apigateway.
if (options && options.url.indexOf("apigateway") >= 0) {
serviceName = "apigateway";
}
if(serviceName == "apigateway" || (options.operation && options.operation.authorizations && options.operation.authorizations[0].sigv4))
{
/**
* All of the below is an adapter to get this thing into the right form for the AWS JS SDK Signer
*/
var parts = options.url.split('?');
var host = parts[0].substr(8, parts[0].indexOf("/", 8) - 8);
var path = parts[0].substr(parts[0].indexOf("/", 8));
var querystring = parts[1];
var now = new Date();
if (!options.headers)
{
options.headers = [];
}
options.headers.host = host;
if(serviceName == "apigateway")
{
//For the swagger endpoint, apigateway is strict about content-type
options.headers.accept = "application/json";
}
options.pathname = function () {
return path;
};
options.methodIndex = options.method;
options.search = function () {
return querystring ? querystring : "";
};
options.region = this.aws.config.region || 'us-east-1';
//AWS uses CAPS for method names, but swagger does not.
options.method = options.methodIndex.toUpperCase();
var signer = new this.aws.Signers.V4(options, serviceName);
//Actually add the Authorization header here
signer.addAuthorization(this.credentialProvider, now);
//SwaggerJS/yourbrowser complains if these are still around
delete options.search;
delete options.pathname;
delete options.headers.host;
return true;
}
return false;
};
对于我们的 AWS API 端点,我们使用 AWS_IAM 授权并希望从 Swagger UI 进行调用。 要成功调用,必须有 2 headers 'Authorization' 和 'x-amz-date'。为了形成 'Authorization',我们使用 following steps from aws doc。 我们必须在每次调用时更改 'x-amz-date' 才能通过授权。 问题是:如何在 Swagger 中编写脚本来签署请求,每次 在 请求发送到 aws 之前 运行? (我们知道如何在加载 Swagger 页面之前指定一次 headers,但是这个过程应该在每次 调用之前 re-run 。
提前致谢。
在 swagger-js 中有 built-in 支持添加 requestInterceptor
来做到这一点。 swagger-ui 项目在后台使用 swagger-js。
像这样简单地创建一个请求拦截器:
requestInterceptor: {
apply: function (request) {
// modify the request object here
return request;
}
}
并在创建时将其应用于您的 swagger 实例:
window.swaggerUi = new SwaggerUi({
url: url,
dom_id: "swagger-ui-container",
requestInterceptor: requestInterceptor,
这里可以在request
object中设置headers(注意,这不是标准javascripthttp请求 object,检查它以获取详细信息)。但是您在这里确实可以访问所有 headers,因此您可以根据需要计算和注入它们。
您可以很容易地将 AWS SDK 中的签名 monkeypatch 签名到 SwaggerJS(以及 SwaggerUI)中。参见 here
我有一个稍微修改过的 SwaggerUI here。给定一些 AWS 凭证和一个 API ID,它将拉下 Swagger 定义,将其显示在 SwaggerUI 中,然后您可以使用 sigv4 调用 API。
Authorizer 实现如下所示:
var AWSSigv4RequestSigner = function(credentialProvider, aws) {
this.name = "sigv4";
this.aws = aws;
this.credentialProvider = credentialProvider;
};
AWSSigv4RequestSigner.prototype.apply = function(options, authorizations) {
var serviceName = "execute-api";
//If we are loading the definition itself, then we need to sign for apigateway.
if (options && options.url.indexOf("apigateway") >= 0) {
serviceName = "apigateway";
}
if(serviceName == "apigateway" || (options.operation && options.operation.authorizations && options.operation.authorizations[0].sigv4))
{
/**
* All of the below is an adapter to get this thing into the right form for the AWS JS SDK Signer
*/
var parts = options.url.split('?');
var host = parts[0].substr(8, parts[0].indexOf("/", 8) - 8);
var path = parts[0].substr(parts[0].indexOf("/", 8));
var querystring = parts[1];
var now = new Date();
if (!options.headers)
{
options.headers = [];
}
options.headers.host = host;
if(serviceName == "apigateway")
{
//For the swagger endpoint, apigateway is strict about content-type
options.headers.accept = "application/json";
}
options.pathname = function () {
return path;
};
options.methodIndex = options.method;
options.search = function () {
return querystring ? querystring : "";
};
options.region = this.aws.config.region || 'us-east-1';
//AWS uses CAPS for method names, but swagger does not.
options.method = options.methodIndex.toUpperCase();
var signer = new this.aws.Signers.V4(options, serviceName);
//Actually add the Authorization header here
signer.addAuthorization(this.credentialProvider, now);
//SwaggerJS/yourbrowser complains if these are still around
delete options.search;
delete options.pathname;
delete options.headers.host;
return true;
}
return false;
};