3scaleの基本的な使い方

はじめに
今回は、3scaleの基本的な使い方を解説します。図1のように、実際にAPIバックエンドに存在する(APIプロバイダが提供する)Hello APIを、3scaleを使って公開するというユースケース(Step 1~Step 3)に沿って解説します。
Hello APIは、”user_key”クエリに指定した値と、リクエストヘッダの値をJSON形式で返却する簡単なAPIです。
$ curl "http://api_backend.oss.example.co.jp:18080/myapp/api/hello?user_key=api_key"
{
"your_user_key": "api_key",
"your_request_headers": {
"User-Agent": [
"curl/7.29.0"
],
"Accept": [
"*/*"
],
"Host": [
"api_backend.oss.example.co.jp:18080"
]
}
}
ここでは、既にこのような簡単なAPIが存在することを前提に解説を進めていきます。
Step 1. APIを公開してみよう
それでは、早速APIバックエンドに存在するHello APIを3scaleで公開してみましょう。以下の3つを設定します。
- プロキシ設定
- APIゲートウェイのURL(クライアントアプリケーション(APIコンシューマ)がコールするURL)と、APIバックエンドのURLとをマッピングする
- 認証用設定
- Hello APIを利用するクライアントアプリケーションを定義する
- 分析用設定
- Hello APIのコール数をカウントできるようにする
まず、管理ポータルのダッシュボードから[NEW API]を選択します(図2)。
3scaleでは、手動でAPIを追加する方法と、サービスディスカバリ機能(OpenShift上にデプロイされたAPIサービスをシームレスに3scaleに取り込む機能)を用いてAPIを追加する方法があります。ここでは、手動でAPIを追加してみましょう(図3)。
これでサービス(3scaleでは“API”と“サービス”は同義)の定義ができあがりました(図4)。以降、具体的な設定をしていきます。
プロキシ設定
まず、プロキシを設定します。Hello APIの概要画面から[Configuration]→[add the base URL of your API and save the configuration]を選択すると、Hello APIのインテグレーション画面が表示されます(図5)。プロキシの設定や認証用の設定など、APIの構成に関わる設定は、基本的にこのインテグレーション画面を用いて設定します。
[Private Base URL]にAPIバックエンドのURL、[Staging Public Base URL]および[Production Public Base URL]にAPIゲートウェイのURLを定義することで、APIゲートウェイのURLとAPIバックエンドのURLとをマッピングします。
APIゲートウェイのURLが2つありますが、これらは名前の通り、それぞれステージング環境用と本番環境用のAPIゲートウェイです。
前述したように、3scaleにはOpenShiftのサービスとしてステージング環境用と本番環境用のAPIゲートウェイが存在します。新しくAPIを追加した場合は、そのゲートウェイに設定したURLとOpenShiftのサービスとをマッピングする必要があります。そのマッピングは、OpenShiftのルートを2つ(ステージング環境用と本番環境用)作成することで実現できます(図6)。
認証用設定
次に認証用の設定をします。Hello APIを利用するクライアントアプリケーションを作成するには、そのクライアントアプリケーションの開発者のアカウントを作成する必要があります。
管理ポータルのダッシュボードから[Audience]→[Create]を選択し、開発者アカウントを作成します(図7)。
開発者アカウントを作成すると、デフォルトでクライアントアプリケーションが1つ作成されます(図8)。このデフォルトクライアントアプリケーションは、デフォルトサービスである”API”を利用するように設定されています。ここではサービスとしてHello APIを用いるため、このデフォルトクライアントアプリケーションは利用できません。
新規クライアントアプリケーションを作成する前に、まずクライアントアプリケーションとサービスとをマッピングするためのアプリケーションプランを作成します。アプリケーションプランとは、流量制御やマネタイズ等のルールをクライアントアプリケーション単位で設定するための枠組みです。
Hello APIの概要画面から[Create Application Plan]を選択すると、アプリケーションプラン作成画面が表示されます(図9)。アプリケーションプランを作成後、作成したアプリケーションプランを[Publish]します。
次に、新規クライアントアプリケーションを作成します(図10)。ここでは、”test application”というアプリケーションを作成します。[Application Plan]には、先ほど作成したHello APIの”Basic”アプリケーションプランを設定します。
分析用設定
最後に分析用の設定を行います。まずはメソッドを設定しましょう。3scaleでは、APIのパスをメソッドと呼びます(図11)。
次にHello APIの概要画面から[Methods]を選択し、新規メソッドとしてHello methodを作成しましょう(図12)。
続けて、作成したメソッドとAPIのパスとをマッピングします。Hello APIのインテグレーション画面で[Add Mapping Rule]を選択し、マッピングルールを追加します(図13)。
以上で設定は完了です。最後にHello APIのインテグレーション画面で[Update & test in Staging Environment]ボタンを押下し、インテグレーションテスト(ステージング環境用のAPIゲートウェイからAPIバックエンドまでの疎通テスト)に成功することを確認しましょう(図14)。
ステージング環境用のAPIゲートウェイを用いて、Hello APIをコールしてみます。”user_key”クエリには、作成したクライアントアプリケーションのAPIキーを付与します。APIキーは、クライアントアプリケーションの概要画面で確認できます。
$ curl "https://hello-3scale-apicast-staging.192.168.99.113.nip.io:443/myapp/api/hello?user_key=cf6e6569d04dc087541b2f49b486a2f1"
{
"your_user_key": "cf6e6569d04dc087541b2f49b486a2f1",
"your_request_headers": {
"Accept": [
"*/*"
],
"User-Agent": [
"curl/7.29.0"
],
"X-Forwarded-Host": [
"hello-3scale-apicast-staging.192.168.99.113.nip.io"
],
"X-Forwarded-Proto": [
"https"
],
"Forwarded": [
"for=192.168.99.113;host=hello-3scale-apicast-staging.192.168.99.113.nip.io;proto=https;proto-version="
],
"X-Forwarded-For": [
"192.168.99.113"
],
"Host": [
"api_backend.oss.example.co.jp:18080"
],
"X-Real-IP": [
"172.17.0.1"
],
"X-3scale-proxy-secret-token": [
"Shared_secret_sent_from_proxy_to_API_backend_9b581ebf1068c969"
],
"X-Forwarded-Port": [
"443"
]
}
}
ステージング環境用のAPIゲートウェイを用いて、Hello APIをコールすることに成功しました。
続いて、本番環境用のAPIゲートウェイを用いてHello APIをコールしてみます。本番環境用のAPIゲートウェイにHello APIをデプロイするためには、コンフィギュレーション画面で[Promote]ボタンを押下します(図15)。
本番環境用のAPIゲートウェイを用いて、Hello APIをコールします。
$ curl "https://hello-3scale-apicast-production.192.168.99.113.nip.io:443/myapp/api/hello?user_key=cf6e6569d04dc087541b2f49b486a2f1"
{
"your_user_key": "cf6e6569d04dc087541b2f49b486a2f1",
"your_request_headers": {
"Accept": [
"*/*"
],
"User-Agent": [
"curl/7.29.0"
],
"X-Forwarded-Host": [
"hello-3scale-apicast-production.192.168.99.113.nip.io"
],
"X-Forwarded-Proto": [
"https"
],
"Forwarded": [
"for=192.168.99.113;host=hello-3scale-apicast-production.192.168.99.113.nip.io;proto=https;proto-version="
],
"X-Forwarded-For": [
"192.168.99.113"
],
"Host": [
"api_backend.oss.example.co.jp:18080"
],
"X-Real-IP": [
"172.17.0.1"
],
"X-3scale-proxy-secret-token": [
"Shared_secret_sent_from_proxy_to_API_backend_9b581ebf1068c969"
],
"X-Forwarded-Port": [
"443"
]
}
}
本番環境用のAPIゲートウェイを用いて、Hello APIをコールすることに成功しました。Hello APIの概要画面から[Analytics]を選択するとHello APIの分析画面が表示され、Hello APIの使用量等を確認できます(図16)。
Step 2. APIのセキュリティを高めよう
デフォルトではAPIキーによるクライアントアプリケーションの認証が有効になっていますが、APIキーは簡単に漏えいするリスクがあり、セキュリティレベルが低いです。エンタープライズ領域で利用できるようなAPIのセキュリティを担保するためには、別の手段を考える必要があります。
ここでは、公開するAPIのセキュリティを高める方法として、以下の2つの方法を紹介します。
- OpenID Connectインテグレーション
- サードパーティのアイデンティティプロバイダと連携し、OpenID Connectの仕様に基づいたAPIリクエストの認証を行う
- OpenID ConnectはOAuth 2.0を拡張した仕様で、API認証フローを定めた仕様のデファクトスタンダード。そのフローの中で認証を司るアイデンティティプロバイダがアクセストークンやリフレッシュトークン、IDトークンを発行する
- シークレットトークン
- 3scaleを通るAPIリクエストに秘密のトークンを付与することで、APIリクエストが3scaleを通ったかをAPIバックエンドが判別できるようにする
OpenID Connectインテグレーション
OpenID Connectインテグレーションを試してみましょう。ここではサードパーティのアイデンティティプロバイダとして、Keycloakのバージョン3.4.3を利用します(Keycloakの構築に関しては、OpenStandiaで提供されている公式ドキュメントの日本語版を参照)。
まず、Keycloakを設定します。ここでは3scaleという名前のレルムを準備します。3scaleレルムに、3scale用のクライアントを設定します(図17)。
ここで設定する項目を表に示します。
表:3scale用クライアントの設定
| 設定項目 | 値 |
|---|---|
| クライアントID | ※ここでは3scale |
| クライアントプロトコル | openid-connect |
| アクセスタイプ | confidential |
| Standard Flowの有効 | オフ |
| Implicit Flowの有効 | オフ |
| ダイレクトアクセスグラントの有効 | オフ |
| サービスアカウントの有効 | オン |
| 付与するサービスアカウントロール | realm-managementクライアントのmanage-clientsロール |
[Credentials]タブで、作成したクライアントのクライアントシークレットを確認しておきましょう。
続いて、Keycloakとのデータ同期に使用する3scaleのコンポーネントであるZyncを設定します。Zync~ Keycloak間はSSL通信が必要なため、KeycloakのCA証明書をZyncにインポートします(下記リストのpublic_keyの項目は、実際には1行です)。
$ keytool -export -alias server -keystore /opt/keycloak-3.4.3.Final/standalone/configuration/application.keystore -file customCA.crt
$ openssl x509 -in customCA.crt -inform der -out customCA.pem -outform PEM
$ curl https://keycloak-server.oss.example.co.jp:8443/auth/realms/master --cacert customCA.pem
{
"realm": "master",
"public_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm64KWQJHSK7JwmfVmXt
VZ2V2KCA2hl2y9aRSTdazBnBVAfBoBcVvsNIDIuSTzgfKqh/RDgAPun39/BA7FXIn7rnoRHlq9MXWY
q3zWzRtDet2nqUux8zBDQeBkvylQB59SC758605wKpTN0YHvt50i8lOTpQBkAeZ8mOKNLMO+GMK9nF
lBQdt+FO+pWXYKfwqcr61Yoz5dHWE2BntmNOdyLcfK9UmXB/z3jvoowfRnx6M1EousUscLr4ErfUyZ
OWjWxt+X8buo3KDeOFbWXYCYoC7tPuGUcCbMv03D610NH1y9gX76h0bzh/UAzqdIGNtS+LoXZZdyxa
rp32CxIRvwwIDAQAB",
"token-service": "https://keycloak-server.oss.example.co.jp:8443/auth/realms/master/protocol/openid-connect",
"account-service": "https://keycloak-server.oss.example.co.jp:8443/auth/realms/master/account",
"tokens-not-before": 0
}
$ oc exec zync-1-gfq2z cat /etc/pki/tls/cert.pem > zync.pem
$ cat customCA.pem >> zync.pem
$ oc create configmap zync-ca-bundle --from-file=./zync.pem
$ oc set volume dc/zync --add --name=zync-ca-bundle --mount-path /etc/pki/tls/zync/zync.pem --sub-path zync.pem --source='{"configMap":{"name":"zync-ca-bundle","items":[{"key":"zync.pem","path":"zync.pem"}]}}'
$ oc patch dc/zync --type=json -p '[{"op": "add", "path": "/spec/template/spec/containers/0/volumeMounts/0/subPath", "value":"zync.pem"}]'
$ oc exec zync-2-zkpmp cat /etc/pki/tls/zync/zync.pem
~~省略:KeycloakのCA証明書が追加されていることを確認します~~
$ oc set env dc/zync SSL_CERT_FILE=/etc/pki/tls/zync/zync.pem
最後に、管理ポータルでOpenID Connectを有効にしましょう。Hello APIのコンフィギュレーション画面から[edit integration settings]を選択し、認証方法をOpenID Connectに変更します(図18)。
Hello APIのインテグレーション画面で、[AUTHENTICATION SETTINGS]→[OpenID Connect Issuer]の欄に3scale用クライアントのクライアントクレデンシャルとKeycloakのURLを設定します(図19)。図中では、[OpenID Connect Issuer]の欄に“https://3scale:xxx@keycloak-server.oss.example.co.jp:8443/auth/realms/3scale”と指定していますが、”xxx”の部分には、3scale用クライアントのクライアントシークレットを指定します。
認証方法をOpenID Connectに変更すると、Hello APIのクライアントアプリケーションであるtest applicationのAPIクレデンシャルとして、APIキーの代わりにクライアントIDとクライアントシークレットが表示されます(図20)。[Add Random key]を押下し、クライアントシークレットを生成しましょう。
クライアントシークレットを生成すると、3scaleはKeycloakの”OpenID Connect動的クライアント登録機能”により、動的にKeycloakのクライアントを登録します。Keycloakのクライアント一覧画面でtest application用のクライアントが作成されていることを確認しましょう(図21)。
以上で設定は完了です。3scaleがサポートする4つのOAuth 2.0フロー(Authorization Code Grant、Resource Owner Password Credentials Grant、Implicit Grant、Client Credentials Grant)のいずれかを用いてアクセストークンを発行し、Hello APIをコールしてみましょう。ここではResource Owner Password Credentials Grantを使います。
$ export token=$(curl -X POST https://keycloak-server.oss.example.co.jp:8443/auth/realms/3scale/protocol/openid-connect/token -d "client_id=17df53c0&client_secret=***&username=tabata&password=***&grant_type=password&scope=openid" | jq -r '.access_token')
$ curl "https://hello-3scale-apicast-production.192.168.99.113.nip.io:443/myapp/api/hello" -H "Authorization: Bearer $token"
{
"your_user_key": null,
"your_request_headers": {
"Authorization": [
"Bearer "
],
"Accept": [
"*/*"
],
"User-Agent": [
"curl/7.64.1"
],
"X-Forwarded-Host": [
"hello-3scale-apicast-production.192.168.99.113.nip.io"
],
"X-Forwarded-Proto": [
"https"
],
"Forwarded": [
"for=192.168.99.1;host=hello-3scale-apicast-production.192.168.99.113.nip.io;proto=https;proto-version="
],
"X-Forwarded-For": [
"192.168.99.1"
],
"Host": [
"api_backend.oss.example.co.jp:18080"
],
"X-Real-IP": [
"172.17.0.1"
],
"X-3scale-proxy-secret-token": [
"Shared_secret_sent_from_proxy_to_API_backend_9b581ebf1068c969"
],
"X-Forwarded-Port": [
"443"
]
}
}
Hello APIをコールすることに成功しました。ちなみにアクセストークンを付与しなかったり、無効なアクセストークンを付与したりすると、以下のように403エラーが返ってきます。
$ curl -v "https://hello-3scale-apicast-production.192.168.99.113.nip.io:443/myapp/api/hello" -H "Authorization: Bearer invalid_token" < HTTP/1.1 403 Forbidden Authentication parameters missing
シークレットトークン
次に、シークレットトークンを試してみます。実はシークレットトークンはデフォルトで有効になっており、前述した確認結果にも、以下のように表示されていました(6~8行目)。
$ curl "https://hello-3scale-apicast-production.192.168.99.113.nip.io:443/myapp/api/hello" -H "Authorization: Bearer $token"
{
"your_user_key": null,
"your_request_headers": {
~~省略~~
"X-3scale-proxy-secret-token": [
"Shared_secret_sent_from_proxy_to_API_backend_9b581ebf1068c969"
],
~~省略~~
}
}
デフォルトでは、”X-3scale-proxy-secret-token”というヘッダに、” Shared_secret_sent_from_proxy_to_API_backend_”という値が入ります。APIバックエンドで、この値をチェックする処理を作り込むことで、APIバックエンドが直接コールされるといったAPIの意図しない使われ方を防ぐことができます。
シークレットトークンに設定する値は、Hello APIのインテグレーション画面の[AUTHENTICATION SETTINGS]→[Secret Token]から変更できます(図22)。
Step 3. 開発者ポータルを使ってみよう
ここまでの説明で、APIを公開し、APIのセキュリティを高めることまではできました。しかし、実際にAPIがどのような仕様なのか、どのように使えばよいのかが分からなければ、開発者はAPIを使ってくれません。ここでは、開発者がAPIを使ってくれるように、開発者向けのポータルを作成しましょう。
3scaleには、開発者ポータルのテンプレートが準備されています。“https://3scale.$(minishift-ip).nip.io”にアクセスしてみましょう(図23)。
トップ画面に加えて、開発者のクライアントアプリケーションのクレデンシャルを確認したり(図24)、
使用量を分析したり(図25)、
仕様を確認したりできます(図26)。
ここでは、トップ画面およびドキュメンテーションをHello API仕様に変更してみましょう。
API仕様の準備
開発者ポータルのドキュメンテーションにHello APIの仕様を表示するため、まずはHello APIの仕様を作成します。フォーマットにはSwagger 2.2.10を用います。
Hello APIの概要画面から[ActiveDocs]→[Create your first spec]を選択し、新規API仕様を作成しましょう(図27)。
Hello APIの仕様は、次のようになります。
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Hello API",
"description": "This API returns the \"user_key\" query and the request headers."
},
"host": "hello-3scale-apicast-production.192.168.99.113.nip.io",
"basePath": "/",
"schemes": [
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/myapp/api/hello": {
"get": {
"description": "Hello API",
"operationId": "hello",
"produces": [
"application/json",
"application/xml",
"text/xml",
"text/html"
],
"parameters": [
{
"name": "user_key",
"in": "query",
"description": "Your API access key",
"required": false,
"x-data-threescale-name": "user_keys",
"type": "string"
},
{
"name": "access_token",
"in": "query",
"description": "Your access token",
"type": "string",
"required": true
}
],
"responses": {
"200": {
"description": "response",
"schema": {
"$ref": "#/definitions/ResponseModel"
}
}
}
}
}
},
"definitions": {
"ResponseModel": {
"type": "object",
"properties": {
"your_user_key": {
"type": "string"
},
"your_request_headers": {
"type": "object"
}
}
}
}
}
Hello APIをコールするためには、アクセストークンが必要になります。アクセストークンを取得するためのAPIの仕様も、Hello APIの仕様と同様の手順で作成します。
{
"swagger": "2.0",
"info": {
"version": "v1",
"title": "OAuth for Hello API",
"description": "OAuth2.0 Client Credentails Flow for authentication of our Hello API."
},
"host": "keycloak-server.oss.example.co.jp:8443",
"basePath": "/auth/realms/3scale/protocol/openid-connect",
"schemes": [
"https"
],
"consumes": [
"application/x-www-form-urlencoded"
],
"paths": {
"/token": {
"post": {
"description": "This operation returns the access token for the API. You must call this before calling any other endpoints.",
"operationId": "oauth",
"parameters": [
{
"name": "client_id",
"description": "Your client id",
"type": "string",
"in": "formData",
"required": true,
"default": "9d1a338f"
},
{
"name": "client_secret",
"description": "Your client secret",
"type": "string",
"in": "formData",
"required": true,
"default": "xxx"
},
{
"name": "grant_type",
"description": "OAuth2 Grant Type",
"type": "string",
"required": true,
"default": "client_credentials",
"in": "formData"
},
{
"name": "scope",
"description": "Scopes",
"type": "string",
"required": true,
"default": "openid",
"in": "formData"
}
],
"responses": {
"200": {
"description": "response"
}
}
}
}
}
}
ポータル画面の変更
次に、開発者ポータル画面を変更していきます。まずは、トップ画面のタイトルを”Echo API”から”Hello API”に変更し、ついでに画面の背景も青色から緑色に変更しましょう。
開発者ポータル画面を変更するには、管理ポータルのダッシュボードから[Audience]→[Developer Portal]→[Content]を選択します。[Homepage]にて、トップ画面のタイトルを変更します(図28)。
[default.css]で、画面の背景を変更します(図29)。
変更を[Save]し、[Publish]すると、開発者ポータルに反映されます(図30)。
続けて、開発者ポータルのドキュメンテーションを変更します。ドキュメンテーションは[Documentation]で変更します。ここでは、アクセストークンを取得するためのAPIの仕様とHello APIの仕様を並べて表示するために、新しく”another-swagger-ui-container”というDOMを設けています(図31)。
変更を[Save]し、[Publish]すると、開発者ポータルに反映されます(図32)。
ここで、実際に開発者ポータルを用いてAPIを試し打ちしてみましょう。各APIをクリックすると、リクエストに必要なパラメータを入力できる欄が表示されます(図33)。クライアントIDとクライアントシークレットの欄には、開発者が持つクライアントアプリケーションのクライアントIDとクライアントシークレットを入力させても良いのですが、API仕様は広く一般に公開することも考えられるので、テスト用のクライアントアプリケーションを作成し、そのクライアントIDとクライアントシークレットをデフォルト値として入れておくのが親切でしょう。
[Try it out!]を押下すると、リクエストおよびレスポンスが表示されます(図34)。
続いて、Hello APIです。Oauth for Hello APIのレスポンスから取得したアクセストークンをパラメータに指定して、試し打ちしてみましょう(図35)。
[Try it out!]を押下すると、無事にHello APIからレスポンスが返ってきました(図36)。
以上で、Hello APIの仕様を開発者ポータルで公開することができました。
おわりに
次回は、APIcast(3scaleのAPIゲートウェイ)の機能を柔軟に拡張可能なポリシーという機能について紹介します。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- 3scaleのAPIゲートウェイの機能を拡張してみよう!
- 3scaleをインストールしてみよう!
- APIファーストの設計ツール「Apicurio」「Microcks」を使ってみよう!
- Keycloakを用いたハードニングの実装方法
- Keycloakのインストールと構築例
- FAPI 1.0に準拠したクライアントアプリケーションと リソースサーバの作り方
- クライアントポリシーを利用したKeycloakの設定方法と、FAPIリファレンス実装の紹介
- NGINX Ingress Controllerの柔軟なアプリケーション制御、具体的なユースケースと設定方法を理解する
- コンテナ上のマイクロサービスの認証強化 ~StrimziとKeycloak~
- クラウドネイティブな環境でKeycloakによるシングルサインオンを実現






































