はじめに
手軽に API を操作したい場合、cURL や Postman、各種プログラミング言語で用意されている HTTP Client などを利用することが多いと思いますが、様々な制約によってそのような環境を用意できないこともあるのではないでしょうか。
この投稿では、Windows 端末(PowerShell)さえあれば最低限 REST API を操作できるということを Cisco Identity Services Engine (以下 ISE)の API を題材に紹介します。
*PowerShell ISE(Integrated Scripting Environment)と紛らわしいですが関係ありません。
いずれも PowerShell でデフォルトで利用できる Invoke-WebRequest
コマンドを利用します。参考のため、併せて同等の操作を Python で実装した例も記載します。
環境
・Windows 10 Pro
・PowerShell version 5.1(Windows インストール後デフォルト設定のまま)
・Cisco ISE version 2.6
準備
Qiita の記事もしくはDevNet の記事を参照ください。
やりたいこと① GET による情報取得
PowerShell 実装例
# SSL エラー回避のための処理
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
# 変数の定義
$username = 'ersadmin' # ERS Admin Username
$password = 'XXXX' # ERS Admin Password
$url = 'https://X.X.X.X:9060/ers/config/internaluser/' # X.X.X.X => ISE's IP address
$credPair = "$($username):$($password)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))
hu
$headers = @{
'Authorization'= "Basic $encodedCredentials";
'Accept'= 'application/json';
'cache-control'= 'no-cache'
}
# API コール
$responseData = Invoke-WebRequest -Uri $url -Method Get -Headers $headers -UseBasicParsing
# 確認方法の例
return $responseData
return $responseData.StatusCode
return $responseData.Header
return $responseData.RawContent
return $responseData.Content
PowerShell にはデフォルトで HTTP クライアントとして Invoke-WebRequest
のほかに Invoke-RestMethod
というコマンドが用意されています。
今回のようにレスポンスのヘッダやコンテンツをまずは人が見やすい形で表示するには Invoke-WebRequest
に -UserBasicParsing
をつける方が向いていて、返り値を直接扱ってなにかしたい場合は Invoke-RestMethod
が便利そうです。
こちらとこちらも参考になります。
参考 Python 実装例
python3.7 (mac) で API コールに Requests ライブラリを利用 (こちらのほうがシンプルですね)
import requests
import json
import base64
host = "X.X.X.X" # ISE's IP address
user = "ersadmin" # ERS Admin Username
password = "XXXXXX" # ERS Admin Password
creds = str.encode(':'.join((user, password)))
encodedAuth = bytes.decode(base64.b64encode(creds))
headers = {
'accept': "application/json",
'authorization': " ".join(("Basic",encodedAuth)),
'cache-control': "no-cache",
}
url = "https://{}:9060".format(host) + "/ers/config/internaluser/"
r = requests.get(url, headers=headers,verify=False) # 今回 ISE が自己署名証明書を利用しているため SSL エラー回避オプションを有効化
data = r.json()
print(json.dumps(data, indent=4))
やりたいこと② PUT による情報更新
PowerShell 実装例
# SSL エラー回避のための処理
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
# 変数の定義
$username = 'ersadmin' # ERS Admin Username
$password = 'XXXX' # ERS Admin Password
$url = 'https://X.X.X.X:9060/ers/config/internaluser/' + "57d1fada-3ab6-4d62-94eb-9b77be36dc7e" # X.X.X.X => ISE's IP address + 対象ユーザの ID が URL となる
$credPair = "$($username):$($password)"
$encodedCredentials = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($credPair))
# ヘッダに Content-type を追加
$headers = @{
'Authorization'= "Basic $encodedCredentials";
'Accept'= 'application/json';
'cache-control'= 'no-cache';
'content-type'= 'application/json'
}
# ボディの定義。パラメータは変更したいアカウントの id, name, password が最低限必要
$body = @{
"InternalUser" = @{
"id" = "57d1fada-3ab6-4d62-94eb-9b77be36dc7e";
"name" = "user1";
"password"="Password123"
}
} | convertTo-Json
# API リクエスト
$responseData = Invoke-WebRequest -Uri $url -Method PUT -Headers $headers -Body $body -UseBasicParsing
# 確認方法
return $responseData.RawContent
return $responseData
return $responseData.StatusCode
return $responseData.Header
return $responseData.Content
参考 Python 実装例
import requests
import json
import base64
host = "X.X.X.X" # ISE's IP address
user = "ersadmin" # ERS Admin Username
password = "XXXXXX" # ERS Admin Password
user_id = "57d1fada-3ab6-4d62-94eb-9b77be36dc7e" # 更新対象ユーザの ID
creds = str.encode(':'.join((user, password)))
encodedAuth = bytes.decode(base64.b64encode(creds))
headers = {
'accept': "application/json",
'content-type': "application/json",
'authorization': " ".join(("Basic",encodedAuth)),
'cache-control': "no-cache",
}
req_body_json = """ {{
"InternalUser" : {{
"id" : "{}",
"name" : "user1",
"password" : "Password123",
"customAttributes" : {{
}}
}}
}}
""".format(user_id,user_name,new_passwd)
url = "https://{}:9060".format(host) + "/ers/config/internaluser/{}".format(id)
r = requests.put(url, headers=headers, data=req_body_json, verify=False)
data = r.json()
print(json.dumps(data, indent=4))
参照
PowerShell における Basic 認証のやりかた
https://pallabpain.wordpress.com/2016/09/14/rest-api-call-with-basic-authentication-in-powershell/
DevNet Cisco ISE ERS API Reference Guide
https://developer.cisco.com/docs/identity-services-engine/
ERS API (External RESTful Services API)
https://www.cisco.com/c/en/us/td/docs/security/ise/2-6/api_ref_guide/api_ref_book/ise_api_ref_ers1.html
Python初心者が、ISE ERS API を利用してスクリプトを書いてみた
https://qiita.com/naixia/items/5c521183c2b606a891b1
Invoke-WebRequestとInvoke-RestMethodの違いは何ですか?
https://www.it-swarm.dev/ja/windows/invokewebrequestとinvokerestmethodの違いは何ですか?/944432281/