GeekFactory

int128.hatenablog.com

Gradle Swagger Generator Plugin 2.6.0をリリースした

Gradle Swagger Generator Plugin 2.6.0をリリースしました。OpenAPI YAMLのバリデーション、コード生成、Swagger UI生成を行うためのプラグインです。

github.com

New features

複数のOpenAPI YAMLを扱う場合に簡潔に記述できるようになりました。これまではYAMLごとに自分でタスクを定義する必要がありましたが、2.6.0からは swaggerSources ブロックに列挙できるようになりました。

swaggerSources {
    petstoreV1 {
        inputFile = file('v1-petstore.yaml')
        code {
            language = 'spring'
            configFile = file('v1-config.json')
        }
    }
    petstoreV2 {
        inputFile = file('v2-petstore.yaml')
        code {
            language = 'spring'
            configFile = file('v2-config.json')
        }
    }
}

コードやSwagger UIを生成する前にYAMLバリデーションを行いたい場合は下記の1行を付け足します。

        code {
            language = 'spring'
            configFile = file('v2-config.json')
            dependsOn validation    // ←追加
        }

また、外部リポジトリからテンプレートを読み込めるようになりました。複数のプロジェクトで共通のテンプレートを利用したい場合に役に立ちます。

repositories {
  // NexusやArtifactoryのリポジトリを指定
  maven {
    url 'https://example.com/nexus-or-artifactory'
  }
  jcenter()
}

dependencies {
  swaggerCodegen 'io.swagger:swagger-codegen-cli:2.2.3'
  // NexusやArtifactoryにpublishされたテンプレートを指定
  swaggerTemplate 'com.example:swagger-templates:1.0.0'
}

swaggerSources {
  petstore {
    inputFile = file('petstore.yaml')
    code {
      language = 'spring'
      // テンプレートJAR内のパスを指定
      templateDir = file("${resolveSwaggerTemplate.destinationDir}/spring-mvc")
    }
  }
}

このように、大規模なプロジェクトでSwagger CodegenやSwagger UIを活用する場合に有用な機能を追加しています。

詳しくはREADMEやサンプルプロジェクトを参照してください。

CloudFront→ELB→EC2構成におけるIPアドレスのアクセス制御

AWSでCloudFront → ELB → EC2の構成を採用する場合に、IPアドレスによるアクセス制御を行う方法を説明します。

方法1: EC2上のWebサーバによるアクセス制御

CloudFrontやELBはリクエストを受けると x-forwarded-for ヘッダにクライアントのIPアドレスを付与します。 このヘッダを利用してIPアドレスによるアクセス制御を実現できます。

CloudFrontとELBを組み合わせる場合は下記のようなヘッダを受け取ります。

クライアント
↓
CloudFront
↓ x-forwarded-for: <クライアントのIPアドレス>
ELB
↓ x-forwarded-for: <クライアントのIPアドレス>, <CloudFrontエッジのIPアドレス>
EC2

クライアントがヘッダを偽装した場合も考慮しておきましょう。もし、クライアントが x-forwarded-for ヘッダを付けてアクセスした場合は下記のようになります。

クライアント
↓ x-forwarded-for: <クライアントが付けた内容>
CloudFront
↓ x-forwarded-for: <クライアントが付けた内容>, <クライアントのIPアドレス>
ELB
↓ x-forwarded-for: <クライアントが付けた内容>, <クライアントのIPアドレス>, <CloudFrontエッジのIPアドレス>
EC2

したがって、 x-forwarded-for ヘッダをカンマで区切って右から2番目の要素を取得すると、クライアントのIPアドレスを取り出すことができます。

Apacheを利用している場合は SetEnvIf正規表現を指定してIPアドレスをチェックします。例えば、 10.20.30.40 に対してアクセスを許可するには下記の設定になります。

<Directory "/var/www/html">
  SetEnvIf x-forwarded-for "(:?^| )10\.20\.30\.40, [\d.]+$" permit_staging
  Order Deny,Allow
  Deny from all
  Allow from env=permit_staging
</Directory>

Apache 2.4からはmod_remoteipモジュールが利用できますが、ヘッダの右から2番目の要素といった指定はできないようです。 クライアントがヘッダを偽装するケースを考慮すると、現時点では正規表現が安全と思います。

CloudFrontやELBが付与する x-forwarded-for ヘッダの仕様は下記を参照してください。

docs.aws.amazon.com

docs.aws.amazon.com

方法2: WAFによるアクセス制御

CloudFrontにWAF(Web Application Firewall)のルールをアタッチすることで、IPアドレスによるアクセス制御を実現できます。 ただし、CloudFrontからELBにアクセスできるようにセキュリティグループを開けておく必要があります。 かなり広いIPアドレスブロックを開けておく必要があるため、攻撃者からELBに直接アクセスされるリスクがあります。

docs.aws.amazon.com

OpenAPIで同じキーのパラメータを複数受け取る

OpenAPIで同じキーのパラメータを複数受け取りたい場合は collectionFormat: multi を使います。

collectionFormat

Determines the format of the array if type array is used. Possible values are:

  • csv - comma separated values foo,bar.

  • ssv - space separated values foo bar.

  • tsv - tab separated values foo\tbar.

  • pipes - pipe separated values foo|bar.

  • multi - corresponds to multiple parameter instances instead of multiple values for a single instance foo=bar&foo=baz. This is valid only for parameters in “query” or “formData”.

Default value is csv.

https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameterCollectionFormat

例えば、以下のように書くと、GETで /bar?foo=1&foo=2&foo=3 を受け取れるようになります。

/bar:
  get:
    parameters:
    - name: foo
      in: query
      type: integer
      collectionFormat: multi