LoginSignup
4
0

【IBM Security Verify】棚卸用にISVの全ユーザー情報をCSV出力する。

Last updated at Posted at 2023-07-01

1. はじめに

 IBM Security Verifyは、IBMが提供しているIDaaS製品です。OktaやAzure ADと同様に、IDaaS製品として豊富な機能とAPIが用意されています。
 IBM Security Verifyでは、CSVでユーザー情報一覧を一括登録するAPIはありますが、CSVで全ユーザーの属性情報一覧をダウンロードするAPIは提供されていません。(2023/5/20現在)
 そこで、IBM Security Verifyの全ユーザー情報を取得し、CSVで出力するPowerShellスクリプトを紹介します。

2. 実装前に2つの注意点

 IBM Security Verifyの既存APIである、ユーザーリスト取得APIを活用します。APIリファレンスはこちら
このAPIを使い、IBM Security Verifyのユーザー情報を全件取得するにあたり、以下2点の注意があります。

2.1. 全件取得するためのアルゴリズム

 ユーザーリスト取得APIは1回の実行で取得できるユーザー件数が2500件までという制限があります。そのため、2500件以上のユーザー数を出力させるためには、API実行を繰り返す必要がありますが、そのアルゴリズムが特殊です。詳細はこちら

2.2. カスタム属性の取得

 ISVのデフォルトの属性だけでなく、カスタム属性として追加した属性をCSVエクスポートに含めたいケースも多いと思います。カスタム属性は、ユーザー情報取得APIの返り値のjsonの中で、以下のようにデータが格納されています。

user.json
                "customAttributes": [
                    {
                        "values": [
                            "カスタム属性の値1"
                        ],
                        "name": "カスタム属性名1"
                    },
                    {
                        "values": [
                            "カスタム属性の値2"
                        ],
                        "name": "カスタム属性名2"
                    },
                    {
                        "values": [
                            "カスタム属性の値3"
                        ],
                        "name": "カスタム属性名3"
                    },
                ],

 カスタム属性の値が入っていないユーザーは、jsonから該当のカスタム属性の項目ごと省略されます。そのため、全ユーザー分のカスタム属性を取得するために、少々アルゴリズムを工夫することがあります。

3. ISVユーザー情報をCSV出力するPowerShellスクリプト

 上の注意点を考慮して作成したスクリプトが以下になります。
実行する際は、ISVテナント名ISVクライアントIDISVクライアントシークレットの3つの変数に値を設定してください。
また、customAttribute1,customAttribute2,customAttribute3の箇所に、ISVに設定したカスタム属性の名称をセットし、必要に応じてcustomAttributeの数を増減させてください。
※当記事は、スクリプトの動作を保証するものはありません。

isv_csv_export.ps1
#
# ※※CSVに出力されるユーザー情報※※
# 1. preferred_username:ログインID
# 2. family_name:姓
# 3. given_name:名
# 4. email:メールアドレス
# 5. カスタム属性1 
# 6. カスタム属性2
# 7. カスタム属性3
# 8. activate:ユーザー状態(True:有効、False:無効)
# 9. id:ISV内部ID
# 10.created:ユーザー作成日時(ISVにユーザーが登録された日時)
# 11.lastLogin:最終ログイン日時(ISVに最後にログインした日時)
# 12.lastPwdChange:最終パスワード変更日時(ISVで最後にパスワード変更した日時)
#   

# ISVテナント名
$tenant_id = "XXXXX.verify.ibm.com"
# ISVクライアントID
$client_id = "XXXXX"
# ISVクライアントシークレット
$client_secret = "XXXXX"

$block = "2022-01-01T00:00:00Z"

#################################################
# アクセストークン取得関数
function getAccessToken{
    $headers=@{}
    $headers.Add("accept", "application/json")
    $headers.Add("content-type", "application/x-www-form-urlencoded")
    $get_url = 'https://' + $tenant_id + '/oidc/endpoint/default/token'
    $body = 'grant_type=client_credentials&client_id=' + $client_id + `
        '&client_secret=' + $client_secret

    try {
        $response = Invoke-WebRequest -Uri $get_url -Method POST -Headers $headers -ContentType 'application/x-www-form-urlencoded' -Body $body
    }catch{
        Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__ 
        Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
        exit
    }
    $response_json = ConvertFrom-Json $response
    return $response_json.access_token
}


#################################################
# URLエンコーディング関数
function UrlEncode {
    param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [string]$Text
    )
    $UrlEncodedText = [System.Web.HttpUtility]::UrlEncode($Text)
    Write-Output $UrlEncodedText
}


# アクセストークン取得
$access_token = getAccessToken
$masterlist = @()

$flag = $true

while ($flag) {
    # ユーザリスト取得APIのパラメータ
    $headers=@{}
    $headers.Add("accept", "application/scim+json")
    $headers.Add("Authorization", "Bearer " + $access_token)
    $encodedblock = UrlEncode -Text ('"'+$block+'"')
    $get_url = 'https://' + $tenant_id + '/v2.0/Users?filter=meta.created%20ge%20' + $encodedblock + '&sortBy=meta.created&sortOrder=ascending&count=2000'

    # ユーザリスト取得API実行
    try {
        $response = Invoke-WebRequest -Uri $get_url -Method GET -Headers $headers
    }catch{
        Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__
        Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription
        exit
    }
    # PowerShellのInvoke-WebRequestでISVデータを取得すると、日本語文字列が???になっていたのでUtf8エンコード
    $response_utf8 = [System.Text.Encoding]::Utf8.GetString($response.RawContentStream.GetBuffer())
    # その際、後ろにNUL(文字コード0000)が埋め込まれてjson変換できなかったので、NUL字を削除
    $res = $response_utf8 -replace "\u0000",""
    # json構造に変換
    $output = ConvertFrom-Json $res

    if ($output.totalResults -lt 2000) {
        $output = $output.Resources
        $masterlist += $output
        Write-Output $masterlist.Length
        $flag = $false
    }
    else {
        $output = $output.Resources
        # 配列の最後の2つのmeta.created が等しい場合は、最後の配列を削除
        while ($output[-1].meta.created -eq $output[-2].meta.created) {
            $output = $output[0..($output.Length - 2)]
        }

        # 末尾の配列のmeta.createdを変数に指定して削除
        $block = $output[-1].meta.created
        $output = $output[0..($output.Length - 2)]

        Write-Output $block
        $masterlist += $output
        Write-Output $masterlist.Length
    }
}

# ディレクトリパスを取得し、YYYYMMDD.csvファイルを生成
$scriptPath = $MyInvocation.MyCommand.Path
$scriptDirectory = Split-Path $scriptPath -Parent
$now = Get-Date
$strYM = $now.ToString("yyyyMMdd")
$csvPath = "$scriptDirectory\$strYM.csv"

# CSVファイルにヘッダ行を書き込む。
$header = "preferred_username,family_name,given_name,email,customAttribute1,customAttribute2,customAttribute3,activate,id,created,lastLogin,lastPwdChange"
$header | Out-File -FilePath $csvPath -Encoding UTF8 -Append

# ユーザー情報リストをCSVに出力
foreach ($i in $masterlist) {
    
    # カスタム属性の初期値 (booleanカスタム属性の場合はfalseをセットする)
    $customAttribute1 = ""
    $customAttribute2 = ""
    $customAttribute3 = ""
    #(カスタム属性を追加する場合は、ここに追加)

    # カスタム属性の属性名を一覧で取得しリスト化
    $custom_names = $i."urn:ietf:params:scim:schemas:extension:ibm:2.0:User".customAttributes.name
    $custom_names_list = $custom_names -split " "
    # カスタム属性の値を一覧で取得しリスト化
    $custom_values = $i."urn:ietf:params:scim:schemas:extension:ibm:2.0:User".customAttributes.values
    $custom_values_list = $custom_values -split " "

    # カスタム属性リストに属性名が存在する場合、それに対応する値をセットする
    if ($custom_names_list.Count -gt 0) {
        for ($k=0; $k -lt $custom_names_list.Count; $k++) {
            switch($custom_names_list[$k]){
                "customAttribute1" {$customAttribute1 = $custom_values_list[$k]; break}
                "customAttribute2" {$customAttribute2 = $custom_values_list[$k]; break}
                "customAttribute3" {$customAttribute3 = $custom_values_list[$k]; break}
                #(カスタム属性を追加する場合は、ここに追加)
            }
        }
    }

    # CSVにユーザー情報を出力
    $row = $i.userName + "," + $i.name.familyName + "," + $i.name.givenName + "," + $i.emails.value + "," + $customAttribute1 + ","  + $customAttribute2 + ","  + $customAttribute3 + "," + $i.active + "," + $i.id + "," + $i.meta.created + "," + $i."urn:ietf:params:scim:schemas:extension:ibm:2.0:User".lastLogin +  "," + $i."urn:ietf:params:scim:schemas:extension:ibm:2.0:User".pwdChangedTime
    $row | Out-File -FilePath $csvPath -Encoding UTF8 -Append
}

exit

4. 参考

本記事を書くにあたり、@fitz さんの以下qiita記事を参考にしました。
IBM Security Verify API + Pythonでユーザー情報一覧を取得する

IBM公式ドキュメント
https://docs.verify.ibm.com/verify/reference/getusers
https://docs.verify.ibm.com/verify/docs/looking-up-users

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0