icon-oneapi.svg
OneAPI

はじめに

Zscaler OneAPIは、OAuth 2.0認証フレームワークを使用して、Zscaler Internet Access (ZIA) API、Zscaler Private Access (ZPA) API、Zscaler Client Connector APIへの安全なアクセスを提供します。OAuth 2.0では、サードパーティー アプリケーションがアクセス トークンを使用して保護されたリソースへの制御されたアクセスを取得できます。OneAPIは、クライアント資格情報OAuthフローを使用します。これにより、クライアント アプリケーションは、プロセスにユーザー認証を関与させることなく、認証サーバーと資格情報をアクセス トークンと交換し、APIリソースへのアクセスを取得できます。

Zscalerの統一アイデンティティー プラットフォームである ZIdentityは、OneAPIの認証サーバーとして機能し、API認証フローに必要な次の機能性をサポートします。

  • Zscaler API サーバーはリソース サーバーとして機能し、アクセス トークンはこのリソース サーバーに対して発行されます。

    閉じる
  • APIクライアント アプリケーションは、認証情報とAPIリソースにアクセスするために必要な範囲とともに、ZIdentity管理ポータルに登録されます。アクセス トークンの有効期間を定義し、APIクライアントのロールと権限の関連付けを管理することもできます。詳細は、APIクライアントの追加およびAPIリソースについてを参照してください。

    閉じる
  • ZIdentityによって公開されるトークン エンドポイントは、クライアント アプリケーションがリソース サーバーのアクセス トークンを取得するために使用されます。

    閉じる

ZIdentityでは、OneAPIリソースにアクセスするために、次のクライアント認証メカニズムがサポートされています。

  • クライアントは、ZIdentity管理ポータルで事前構成されたクライアント シークレットを使用して認証されます。一度に最大2つのシークレットを作成して使用できます。

    閉じる
  • クライアントによって生成され、クライアントの秘密キーによって署名されたJWTアサーションが認証に使用されます。クライアント アサーションは、お客様の構成に応じて次のメソッドを使用して検証できます。

    • [クライアントJWK URL]:クライアント アサーション署名は、公開キーをJWK形式で公開するURLを使用して検証されます。
    • [証明書/公開キー]:クライアント アサーション署名は、ZIdentity管理ポータルにアップロードされた公開キーまたはX.509証明書を使用して検証されます。
    閉じる

APIクライアントが認証リクエストを送信すると、ZIdentityは、使用される認証メカニズムに応じてクライアント シークレットまたはアサーションを検証し、検証が成功すると認証グラント(つまり、アクセス トークン)を発行します。このアクセス トークンは、クライアントがAPIリソースへのアクセスをリクエストするために使用されます。

前提条件

組織は、OneAPIを利用する前に、次の前提条件を満たす必要があります。

  • 組織にOneAPIとZIdentityのサブスクリプションがあることを確認します。これらのサービスにアクセスするには、Zscalerアカウント チームにお問い合わせください。
  • クライアント アプリケーションを必要な範囲でZIdentity管理ポータルに登録し、適切に構成します。詳細は、APIクライアントの追加を参照してください。

OneAPIへのアクセス

以下のステップを従って、OneAPIに安全にアクセスできます。

  • OneAPIは、APIリクエストが行われるベースURLのホストとしてapi.zsapi.netを使用します。各APIには一意のbasePathがあり、その結果、次のように異なるベースURLが生成されます。

    APIベース パスベースURL
    ZIA API/zia/api/v1https://api.zsapi.net/zia/api/v1
    ZPA API

    サポートされているベースパスは、次の通りです。

    • /zpa/mgmtconfig/v1
    • /zpa/mgmtconfig/v2
    • /zpa/userconfig/v1

    サポートされているベースURLは、次の通りです。

    • https://api.zsapi.net/zpa/mgmtconfig/v1
    • https://api.zsapi.net/zpa/mgmtconfig/v2
    • https://api.zsapi.net/zpa/userconfig/v1
    Zscaler Client Connector API/zcc/papi/public/v1https://api.zsapi.net/zcc/papi/public/v1

    ZPA APIのベースURIは/mgmtconfig/v1/mgmtconfig/v2です。エンドポイントがSCIM属性の詳細とSCIMグループの詳細を取得するために、/userconfig/v1がベースURIとして使用されます。

    すべてのエンドポイントは、ベースURLに対して相対的です。例えば、/usersなどのZIA APIエンドポイントを呼び出すには、APIリクエストをURL、https://api.zsapi.net/zia/api/v1/usersに送信する必要があります。同様に、ZPAエンドポイントとZscaler Client ConnectorエンドポイントへのAPIリクエストでは、エンドポイントが末尾に追加された、それぞれのベースURLを使用する必要があります。

    Zscalerは、ホストとしてapi.beta.zsapi.netを使用するOneAPI用のベータ エンドポイントもサポートしています。basePathは、前のテーブルにリストしたように、各APIで同じままです。たとえば、/usersエンドポイントをベータ経由で呼び出すには、APIリクエストをURL:https://api.beta.zsapi.net/zia/api/v1/usersに送信する必要があります。

    閉じる
  • OneAPIリソースにアクセスする前に、クライアント アプリケーションは、その資格情報を承認サーバー(つまり、ZIdentity)と交換することにより、承認トークン(つまり、ベアラー トークン)を取得する必要があります。アクセス トークンは、認証のためにOneAPIへの後続の呼び出しに渡される必要があります。

    アクセス トークンを取得するには、クライアント アプリケーションを設定して、必要なパラメーターとともにPOSTリクエストをZIdentityのhttps://<バニティー ドメイン>.zslogin.net/oauth2/v1/tokenトークン エンドポイントに送信する必要があります。ここで<バニティー ドメイン>は、組織で使用されているドメイン名を指します。リクエスト パラメーターとペイロードは、クライアントが認証にシークレットを使用するか、アサーション(秘密キーJWT認証を使用)を使用するかによって異なる場合があります。

    • この認証のメソッドでは、クライアント資格情報は、clientID:ClientSecretの形式で基本認証を通じて送信するか、リクエスト ペイロードを通じてclient_idclient_secretのパラメーターとして送信できます。詳細は、OAuth 2.0 RFC 6749のセクション2.3を参照してください。リクエストで送信されたクライアント資格情報は、ZIdentity管理ポータルで構成されたクライアント登録の詳細を使用してZIdentityによって検証されます。

      承認リクエストには、https://api.zscaler.com値で設定されたaudienceパラメーターが含まれている必要があります。

      以下は、基本認証を使用して提示されたクライアント資格情報でのリクエストの例です。この例では、バニティ ドメインのプレースホルダーを組織で使用されているドメイン名に置き換え、資格情報のプレースホルダーをclientID:clientSecret文字列のBase64エンコード値に置き換える必要があります。

      POST /oauth2/v1/token HTTP/1.1
      Host: <バニティー ドメイン>.zslogin.net
      Authorization: Basic <資格情報>
      Content-Type: application/x-www-form-urlencoded
      {
      "grant_type": "client_credentials",
      "audience": "https://api.zscaler.com"
      }

      以下は、リクエスト ペイロードで送信されたクライアントIDとクライアント シークレット情報を含むリクエストの例です。この例では、クライアントIDとクライアント シークレットが強調表示され、対応する値を入力する必要がある場所が示されています。また、バニティー ドメインのプレースホルダーは、組織で使用されているドメイン名に置き換える必要があります。

      POST /oauth2/v1/token HTTP/1.1
      Host: <バニティー ドメイン>.zslogin.net
      Content-Type: application/x-www-form-urlencoded
      {
      "grant_type": "client_credentials",
      "client_id": "<クライアントID>",
      "client_secret": "<クライアント シークレット>",
      "audience": "https://api.zscaler.com",
      }

      リクエストが成功すると、次のように、アクセストークンとその有効期限がJSON構造で200 OKレスポンスがクライアントに返されます。

      {
      "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...vnI4T_H2rfze0c1Fk",
      "token_type": "Bearer",
      "expires_in": 3600
      }
      

      クライアント シークレットは、シークレットが初めて作成されたときにのみZIdentity管理ポータルでアクセスできます。作成時にクライアント シークレットが表示されたら、必ずコピーして安全に保管してください。認証トークンの有効期限は、ZIdentity管理ポータルのAPIクライアントに対して設定されます。

      トークン エンドポイントへのPOSTリクエストが失敗した場合、レスポンス コードは400エラー コードを返します。

      閉じる
    • 秘密キーJWT認証メソッドでは、APIクライアントは秘密キーを使用してJWTを作成し、デジタル署名し、認証リクエストでクライアント アサーションとしてJWTを送信します。クライアント アサーションはリクエストから抽出され、クライアントの公開キーを使用して承認サーバー(つまり、ZIdentity)によって検証されます。詳細は、RFC 7521およびRFC 7523を参照してください。

      クライアントは、クライアント認証の情報を含むJWTを提示するclient_assertionパラメーターで、トークン エンドポイントにPOSTリクエストを行います。アサーションには標準のJWT要求が含まれていることが想定されており、追加の明示的な要件はありません。リクエストには、次に説明する他の必要なパラメーターも含める必要があります。

      承認リクエストには、https://api.zscaler.com値で設定されたaudienceパラメーターが含まれている必要があります。

      対応する値を入力する必要がある場所を示すためにクライアントIDとクライアント アサーションが強調表示されたトークン エンドポイントへのPOSTリクエストの例。

      POST /oauth2/v1/token HTTP/1.1
      Host: <バニティー ドメイン>.zslogin.net
      Content-Type: application/x-www-form-urlencoded
      {
      "grant_type"="client_credentials"
      "client_id"="<クライアントID>"
      "client_assertion"="<クライアント アサーションJWT>"
      "client_assertion_type"="urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
      "audience"="https://api.zscaler.com"
      }

      リクエストが成功すると、次のように、アクセストークンとその有効期限がJSON構造で200 OKレスポンスがクライアントに返されます。

      {
      "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6Ikp...vnI4T_H2rfze0c1Fk",
      "token_type": "Bearer",
      "expires_in": 3600
      }

      アサーションには、追加の明示的な要件がない標準のJWT要求が含まれることが想定されます。署名は、JWKSエンドポイントからフェッチした公開キーで、または構成済み公開キーもしくはX.509証明書を使用して検証可能である必要があり、発行とトークン有効期限が検証される必要があります。ZIdentity管理ポータルでは、クライアントのJWKSエンドポイントを構成するか、公開キーまたは証明書を直接アップロードすることができます。次いで、ZIdentityはこれを使用して、認証リクエストでクライアントから送信されたJWTを暗号的に検証します。詳細は、APIクライアントの追加を参照してください。

      トークン エンドポイントへのPOSTリクエストが失敗した場合、レスポンスで400エラー コードが返されます。

      閉じる
    閉じる
  • API呼び出しを行うとき、クライアントは認証のために各リクエストで承認トークン(つまり、ベアラー トークン)を渡す必要があります。クライアントは、ベアラー認証スキームを使用して、リクエストの[承認]ヘッダーでアクセス トークンを提示する必要があります。

    ZPAエンドポイントへのAPIリクエストには、顧客のZPAテナントIDを表すcustomerIdパラメーターが必要です。開始する前に、次のいずれかの方法でcustomerId値を取得したことを確認してください。

    次に、OneAPIリソースに対するリクエストとレスポンスの例を示します。

    • 次の例では、POSTリクエストを/urlLookupに送信して、ZIA内の指定済みURLリストのカテゴリーを検索します。ZIdentityから取得したベアラー トークンは、リクエストの承認ヘッダーで渡す必要があります。

      POST /zia/api/v1/urlLookup HTTP/1.1
      Host: api.beta.zsapi.net
      Content-Type: application/json
      Authorization: Bearer <アクセス トークン>
      Content-Length: 48
      [ 
      "viruses.org", 
      "facebook.com", 
      "bbc.com" ]

      このリクエストにレスポンスが成功すると、URLのリストとそのカテゴリー情報が返されます。

      [ {
      "url": "viruses.org",
      "urlClassifications": [
      "MISCELLANEOUS_OR_UNKNOWN"
      ],
      "urlClassificationsWithSecurityAlert": []
      },
      {
      "url": "facebook.com",
      "urlClassifications": [
      "SOCIAL_NETWORKING"
      ],
      "urlClassificationsWithSecurityAlert": []
      },
      {
      "url": "bbc.com",
      "urlClassifications": [
      "NEWS_AND_MEDIA"
      ],
      "urlClassificationsWithSecurityAlert": []
      } ]                     

      Zscalerでは、ルックアップ用のURLをバッチで送信することをお勧めします。各リクエストには最大100個のURLを含めることができ、各URLは1,024文字を超えることはできません。

      APIサービスのアップグレードまたは定期メンテナンスが原因でAPI呼び出しが失敗した場合、次のサンプルのレスポンスに示すように、403エラー コードが返されます。APIサービスは、この期間中のGETリクエスト経由の読み取り操作のみをサポートします。

      HTTP/1.1 403
      x-zscaler-mode: read-only
      {
          "code": "STATE_READONLY",
          "message": "The API service is undergoing a scheduled upgrade and is in read-only mode."
      }

      ZIAへのAPI呼び出しを行うときは、次のベスト プラクティスを考慮してください。

      • ZIdentity管理ポータル内のAPIクライアントに対してアクセス トークンの有効期間が適切な値に設定されていることを確認します。
      • リソースを更新するときは、必ずPUT要求の前にGET要求を送信してください。これにより、リソース全体を新しい値で更新する前に、リソースの現在の値が取得されます。
      閉じる
    • 次の例では、GETリクエストを/mgmtconfig/v1/admin/customers/{customerId}/applicationに送信し、customerIdパラメーターを含めることで、ZPA内のすべてのApplication Segmentsのリストを取得します。

      次のPythonスクリプトを使用して、すべてのApplication Segmentのリストを取得します。customerIdパラメーターは、ZPAテナントIDを入力する必要がある場所を示すために強調表示され、ZIdentityから取得したベアラー トークンを入力する必要がある場所でプレースホルダー テキストが使用されます。

      import requests
      url = "https://api.zsapi.net/zpa/mgmtconfig/v1/admin/customers/{customerId}/application?page=1&pagesize=20&search="
      payload={}
      headers = {
      'Accept': '*/*',
      'Authorization': 'Bearer <アクセス トークン>'
      }
      response = requests.request("GET", url, headers=headers, data=payload)
      print(response.text)

      このリクエストにレスポンスが成功すると、Application Segmentのリストとその詳細が返されます。

      {
      "totalPages":"1",
      "list":[
      {
      "creationTime":"1617135729",
      "modifiedBy":"7207654021241",
      "id":"7207654021241",
      "domainNames":[
      "example.com"
      ],
      "name":"example",
      "serverGroups":[
      {
      "id":"7207654021241",
      "creationTime":"1617134731",
      "modifiedBy":"7207654021241",
      "name":"SIPA",
      "enabled":true,
      "configSpace":"DEFAULT",
      "dynamicDiscovery":true
      }
      ],
      "enabled":true,
      "passiveHealthEnabled":true,
      "tcpPortRanges":[
      "443",
      "443"
      ],
      "doubleEncrypt":false,
      "configSpace":"DEFAULT",
      "bypassType":"NEVER",
      "healthCheckType":"DEFAULT",
      "isCnameEnabled":true,
      "ipAnchored":true,
      "healthReporting":"ON_ACCESS",
      "segmentGroupId":"7207654021241",
      "segmentGroupName":"SIPA"
      },
      {
      "modifiedTime":"1617135436",
      "creationTime":"1613673797",
      "modifiedBy":"7207654021241",
      "id":"7207654021241",
      "domainNames":[
      "www.example.com"
      ],
      "name":"example",
      "serverGroups":[
      {
      "id":"7207654021241",
      "creationTime":"1613673769",
      "modifiedBy":"7207654021241",
      "name":"ZPA",
      "enabled":true,
      "configSpace":"DEFAULT",
      "dynamicDiscovery":true
      }
      ],
      "enabled":true,
      "passiveHealthEnabled":true,
      "tcpPortRanges":[
      "80",
      "80"
      ],
      "doubleEncrypt":false,
      "configSpace":"DEFAULT",
      "bypassType":"NEVER",
      "healthCheckType":"DEFAULT",
      "isCnameEnabled":true,
      "ipAnchored":false,
      "healthReporting":"ON_ACCESS",
      "segmentGroupId":"7207654021241",
      "segmentGroupName":"ZPA"
      },
      {
      "creationTime":"1617134731",
      "modifiedBy":"7207654021241",
      "id":"7207654021241",
      "domainNames":[
      "docs.example.com"
      ],
      "name":"docs.example.com",
      "serverGroups":[
      {
      "id":"7207654021241",
      "creationTime":"1617134731",
      "modifiedBy":"7207654021241",
      "name":"SIPA",
      "enabled":true,
      "configSpace":"DEFAULT",
      "dynamicDiscovery":true
      }
      ],
      "enabled":true,
      "passiveHealthEnabled":true,
      "tcpPortRanges":[
      "54",
      "65535"
      ],
      "doubleEncrypt":false,
      "configSpace":"DEFAULT",
      "bypassType":"NEVER",
      "healthCheckType":"DEFAULT",
      "isCnameEnabled":true,
      "ipAnchored":true,
      "healthReporting":"ON_ACCESS",
      "segmentGroupId":"7207654021241",
      "segmentGroupName":"SIPA"
      },
      {
      "creationTime":"1613762719",
      "modifiedBy":"7207654021241",
      "id":"7207654021241",
      "domainNames":[
      "www.example.com"
      ],
      "name":"example",
      "serverGroups":[
      {
      "id":"7207654021241",
      "creationTime":"1613673769",
      "modifiedBy":"7207654021241",
      "name":"ZPA",
      "enabled":true,
      "configSpace":"DEFAULT",
      "dynamicDiscovery":true
      }
      ],
      "enabled":true,
      "passiveHealthEnabled":true,
      "tcpPortRanges":[
      "443",
      "443"
      ],
      "doubleEncrypt":false,
      "configSpace":"DEFAULT",
      "bypassType":"NEVER",
      "healthCheckType":"DEFAULT",
      "isCnameEnabled":true,
      "ipAnchored":false,
      "healthReporting":"ON_ACCESS",
      "segmentGroupId":"7207654021241",
      "segmentGroupName":"ZPA"
      },
      {
      "creationTime":"1616516461",
      "modifiedBy":"7207654021241",
      "id":"7207654021241",
      "domainNames":[
      "*.example.com"
      ],
      "name":"test-wildcard",
      "description":"&amp;#x2a;&amp;#x2e;example&amp;#x2e;com",
      "serverGroups":[
      {
      "id":"7207654021241",
      "creationTime":"1613673769",
      "modifiedBy":"7207654021241",
      "name":"ZPA",
      "enabled":true,
      "configSpace":"DEFAULT",
      "dynamicDiscovery":true
      }
      ],
      "enabled":true,
      "passiveHealthEnabled":true,
      "tcpPortRanges":[
      "443",
      "443",
      "80",
      "80"
      ],
      "doubleEncrypt":false,
      "configSpace":"DEFAULT",
      "bypassType":"NEVER",
      "healthCheckType":"DEFAULT",
      "isCnameEnabled":true,
      "ipAnchored":false,
      "healthReporting":"ON_ACCESS",
      "segmentGroupId":"7207654021241",
      "segmentGroupName":"ZPA"
      }
      ]
      }
      閉じる

      リクエストでマイクロテナントの一意の識別子であるmicrotenantIdを渡す場合は、次の条件が適用されます。

      • マイクロテナント内にいる場合は、そのマイクロテナントからデータを取得するためのAPI呼び出しを行うときに、microtenantIdフィールドを渡す必要があります。microtenantIdは、ZPA APIを使用してプログラムで取得できます。特定の操作へのアクセスは、マイクロテナント内にいると制限されます。
      • デフォルトのマイクロテナント内にいる場合は、デフォルトのマイクロテナントからデータを取得するリクエストを行うときに、microtenantId0として渡します。
      • テナントに関連付けられているすべての顧客からデータを取得するには、microtenantIdをnullとして渡します。
      閉じる
    • 次の例では、特定のデバイスのワンタイムパスワードをZscaler Client Connectorから取得します。取得は、GETリクエストを/getOtpに送信すると共にudidデバイスのパラメーターを含めることで行います。

      udidパラメーターは、Zscaler Client Connectorに登録されたデバイスに対して生成された一意のデバイス識別子を表します。この値は、Zscaler Client Connector APIを使用してプログラムで取得できます。

      次のPythonスクリプトを使用して、ワンタイム パスワードを取得します。スクリプトには、デバイスのUDIDを入力し、プレースホルダーが赤で強調表示されているZIdentityから取得したベアラー トークンを含めます。

      import requests
      url = "https://api.zsapi.net/zcc/papi/public/v1/getOtp?udid={udid}" 
      headers = { 
      'Accept': '*/*',
      'Authorization': 'Bearer <アクセス トークン>'
      }
      response = requests.request("GET", url, headers=headers)
      print(response.text)

      リクエストが成功すると、次のようなレスポンスが返されます。

      {
       "otp" : "kg08abdcp1"
      }

      Zscaler Client ConnectorへのAPI呼び出しを行うときは、次のベスト プラクティスを考慮してください。

      • すべてのエンドポイントにUTF-8エンコーディングを使用します(たとえば、JavaScriptのencodeUriComponent()関数を使用してUTF-8にエンコードします)。
      • リソースを更新するときは、必ずPUT/POST要求の前にGET要求を送信してください。これにより、リソース全体を新しい値で更新する前に、リソースの現在の値が取得されます。更新後、そのリソースに対する次のGET要求は新しい値を返します。この方法を使用すると、GET呼び出しとPUT/POST呼び出しの間で更新が欠落する可能性を回避できます。
      • すべてのURL要求文字列にランダムに生成された番号を持つダミー引数を追加することで、APIコールしのキャッシュを防止します。たとえば、次のように指定します:GET /getOtp?_=123456
      • スクリプトごとに専用のユーザーを作成します。同時に実行される複数のスクリプトで同じキーを使用しないでください。
      閉じる

    APIリクエストを受信すると、Zscalerサービスはアクセス トークンを検証し、承認が成功した場合はリクエストを承諾します。Zscalerサービスは、リクエストの承認ヘッダーからJWTを抽出し、クライアントの公開キーまたはX.509証明書を使用してJWT署名を検証し、JWT要求を検証します。検証が成功すると、クライアントはリクエストされたAPIリソースにアクセスできるようになります。

    APIにアドホック リクエストを送信するには、ZscalerではPostman REST APIクライアントの使用をお勧めします。

    ZIA APIエンドポイントへのAPI呼び出しを行う場合は、設定を変更した後、/status/activateにPOSTリクエストを送信して変更をアクティブ化する必要があります。

    ベスト プラクティスとして、Zscalerでは、複数の構成の変更を行う場合は、変更をグループ化して1回アクティブ化することを推奨します。アクティベーション ステータスを取得するには、/statusにGETリクエスト送信します。ただし、変更を元に戻すことはできず、キューに入れられたアクティベーションをキャンセルすることはできません。

    競合状態を回避するには、スクリプトの実行中にZIA管理ポータルを使用して構成設定を手動で変更しないでください。Zscalerサービスは、ユーザーが編集中に構成をロックする可能性があります。複数のユーザーが同時に編集している場合、1人のユーザーのみの変更が成功し、残りのユーザーは409エラー(EDIT_LOCK_NOT_AVAILABLE)を受け取る可能性があります。

    競合状態が発生し、409エラー コードが返された場合は、Zscalerでは、数秒の待機サイクルを追加して、回復を再試行することをお勧めします。

    アクティベーション ステータスを取得するには、/statusにGETリクエストを送信します。ただし、変更を元に戻すことはできず、キューに入れられたアクティベーションをキャンセルすることもできません。

    閉じる

    閉じる

レート制限とHTTPステータス コードの詳細については、レート制限についての理解およびレスポンス コードとエラー メッセージについての理解を参照してください。APIで問題が発生した場合は、Zscalerサポートにお問い合わせください。

関連記事s
OneAPIについてはじめにPostman REST APIクライアントの設定