如何在请求之前在Swagger中计算AWS签名V4

时间:2016-03-31 14:19:23

标签: amazon-web-services swagger swagger-ui

对于我们的AWS API端点,我们使用AWS_IAM授权,并希望通过Swagger UI进行调用。 要成功拨打电话,必须有2个标题'授权'和' x-amz-date'。形成授权'我们使用following steps from aws doc。 我们必须改变x-amz-date'每次打电话都需要通过授权。 问题是:如何在Swagger中编写脚本来签署请求,每次请求发送给aws之前运行? (我们知道如何在加载Swagger页面之前指定两个标题,但是在每次调用之前,应该重新运行。)

提前致谢。

2 个答案:

答案 0 :(得分:3)

swagger-js中有内置支持,可添加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对象中的标头(请注意,这不是标准 javascript http请求对象,请检查详细信息)。但您可以在此处访问所有标题,因此您可以根据需要计算并注入它们。

答案 1 :(得分:1)

您可以非常轻松地将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;
};