
JMeterでMS社のサービスにログインする方法
はじめに
こんにちは、DevOps推進2グループの李です。現在進行中の案件はJMeterを使って、負荷テストスクリプトをメンテナンスしていますが、最初に直面した課題はJMeterでAzureにログインすることでした。当時は一週間かかって課題を克服しました。ですので、ログインする処理を皆さんにシェアしたいと思います。
※ 本記事ではわかりやすくする為、Azure環境へのログインではなく、MS社のOutlookの事例を紹介しております。 また、SSOサービスを利用されている場合ではログインルートが異なる点にもご注意ください。
JMeterバージョンとOutlook環境は下記です。
JMeter:JMeter-5.4.3 https://jmeter.apache.org/download_jmeter.cgi
Outlookサイト:https://outlook.live.com/owa/
必要な知識
JMeterの基本操作
正規表現の書き方
ブラウザの開発ツールの使い方
この記事はJavaの書き方とJMeterのThread GroupかHTTP Requestの設定とブラウザの開発ツールの使い方に関する基本知識があることを想定します。
MS社サービスログインの流れ
MS社のサービスについて、login.microsoftonline.comの共通ログインサービスを使い、メールアドレスとパスワードは二段階で別のページに入力することが特徴です。
ログインの流れは下記のステップを参考にしてください。先ずはOutlookのホームページにアクセスし、ログインURLを取得しまし。次にメールアドレスとパスワードの順番でサーバーに送り、トークンを取得します。 最後は取得したトークンをOutlookに送りログインします。

実装する方法
Outlookログインの実装に入る前に、「User Defined Variables」とHTTP Cookie Managerを追加して、User Defined Variablesにログインするメールアドレス(mail)とパスワード(password)を記載します。下図の基本エレメントを追加した後、ログインまでの手順を説明します。

Step1:Outlookサイトにアクセスして、遷移先を取得する
ログインページには必須のパラメータがたくさんあるので、パラメータを取得するため、ホームページから「Sign In」ボタンを押した時のリクエストからログインページのURLを取得します。
「Sign In」ボタンを押した時に次のステップで使用するURLは https://outlook.live.com/owa/?nlp=1 のレスポンスのlocationの中に記載されているので、下記の正規表現式でURLを取得できます。
リクエスト
メソッド :GET
URL : outlook.live.com
パス : owa/
パラメータ : nlp=1
抽出する変数
変数命名 : url
抽出先 : ヘッダー
正規表現式 : https://login.live.com/(.*)


Step2:遷移先からトークンを取得する
Step1で取得したURLをこのステップのパスとしてリクエストを送信します。MS社のログインは別のログインサーバー(login.live.com)でログイン処理を完了したら、貰ったトークンを元のサーバーに送って、ログイン処理をします。
このステップの目標はbsとflowTokenなどの変数を取得することです。bsは次のリクエストのパスです。flowTokenとuaidはリクエストのボディーです。
リクエスト
メソッド : POST
URL : login.live.com
パス : ${url}
パラメータ: 空欄
抽出する変数
変数命名 : bs
抽出先 : ボディー
正規表現式: bs:'https://login.live.com/GetCredentialType.srf(.*)',cR:
変数命名 : flowToken
抽出先 : ボディー
正規表現式: name="PPFT" id="i0327" value="(.*)"/>
変数命名 : uaid
抽出先 : ボディー
正規表現式: uaid=(.*)"/>Microsoft
変数命名 : hpgid
bs抽出先 : ボディー
正規表現式: hpgid:(.*),sRequestCountry

Step3:メールアドレスを入力して、次のページへ遷移
このステップは前段のステップで取得したbsをパスとして、flowTokenなどをレスポンスボディーで送ります。このステップでは抽出するものはありません。
リクエスト
メソッド : POST
URL : login.live.com
パス : GetCredentialType.srf${bs}
パラメータ: 空欄
ボディー:
{"username":"${mail}","uaid":"${uaid}","isOtherIdpSupported":true,"checkPhones":false,"isRemoteNGCSupported":true,"isCookieBannerShown":false,"isFidoSupported":true,"forceotclogin":false,"otclogindisallowed":false,"isExternalFederationDisallowed":false,"isRemoteConnectSupported":false,"federationFlags":3,"isSignup":false,"flowToken":"${flowToken}"}

Step4:パスワードを入力して、次のページへ遷移
このステップも、ステップ2で取得したbsをパスとして、flowTokenはPPFTのヴァリューとして送ります。レスポンスは次のリクエストのURLと新たなflowTokenを取得します。
このリクエストのメールアドレスとパスワードはどちらも平文なので、MS社の安全性はちょっと心配ですね。
リクエスト
メソッド : POST
URL : login.live.com
パス : ppsecure/post.srf${bs}
パラメータ: 空欄
ボディー:
i13=0&login=${mail}&loginfmt=${mail}&type=11&LoginOptions=3&lrt=&lrtPartition=&hisRegion=&hisScaleUnit=&passwd=${password}&ps=2&psRNGCDefaultType=&psRNGCEntropy=&psRNGCSLK=&canary=&ctx=&hpgrequestid=&PPFT=${flowToken}&PPSX=PassportRN&NewUser=1&FoundMSAs=&fspost=0&i21=0&CookieDisclosure=0&IsFidoSupported=1&isSignupPost=0&i19=564972
抽出する変数:
変数命名: flowToken2
抽出先: ボディー
正規表現式: sFT:'(.*)',cO
変数命名: urlPost
抽出先: ボディー
正規表現式:
urlPost:'https://login.live.com/ppsecure/post.srf(.*)', urlApplicationInsightsEndpoint

Step5:トークン取得する
パスワードを送ったら、login.live.comサーバーからいろんなトークンが取得できます。取得したトークンはOutlookサーバーで使うので、このステップはlogin.live.comサーバーの最後のステップで、ログインフロー上で一番重要なステップです。トークンの絞り込み条件を間違えれば、ログインは失敗と判定されます。
このステップでも次のリクエストで使うURLとボディーの変数を取得します。必要な変数は下記の一覧です。
リクエスト
メソッド : POST
URL : login.live.com
パス : ppsecure/post.srf${urlPost}
パラメータ: 空欄
ボディー:
LoginOptions=3&type=28&ctx=&hpgrequestid=&PPFT=${flowToken2}&i19=523407
抽出する変数:
変数命名 :urlPost2
抽出先 : ボディー
正規表現式:"fmHF" action="https://outlook.live.com/(.*)" method="post"
変数命名 :wbids
抽出先 : ボディー
正規表現式:id="wbids" value="(.*)"><input type="hidden" name="pprid"
変数命名 :pprid
抽出先 : ボディー
正規表現式:id="pprid" value="(.*)"><input type="hidden" name="wbid"
変数命名 :wbid
抽出先 : ボディー
正規表現式:id="wbid" value="(.*)"><input type="hidden" name="NAP"
変数命名 :NAP
抽出先 : ボディー
正規表現式:id="NAP" value="(.*)"><input type="hidden" name="ANON"
変数命名 :ANON
抽出先 : ボディー
正規表現式:id="ANON" value="(.*)"><input type="hidden" name="t"
変数命名 :t
抽出先 : ボディー
正規表現式:id="t" value="(.*)"></form>

Step6:Outlookサイトにトークンを送る
このステップはlogin.live.comサーバーで貰ったものをOutlookのサーバーに送って、ログインフローを完了させます。
リクエスト
メソッド : POST
URL : outlook.live.com
パス : ${urlPost2}
パラメータ: 空欄
ボディー:
wbids=${wbids}&pprid=${pprid}&wbid=${wbid}&NAP=${NAP}&ANON=${ANON}&t=${t}

まとめ
上記の6ステップで作ったスクリプトは下図のイメージです。このスクリプトを実行したら、最後のステップでhttps://outlook.live.com/mail/0/に遷移されます。
最後のレスポンスでこの赤枠のURLが表示されたら、ログイン処理が成功したと判断します。


SAASは今後さらに発展していくサービスで、あるサイトからログインしてあらゆるサービスを使うことが主流になります。SAASサービスで負荷テストを実行する上で、負荷ツールでログイン技術は欠かせないと思います。今回はOutlookを例として作りましたが、ほかのサービスにおいても、この行程と同じようなリクエストとレスポンスを解析すれば、ほかのサービスのログインスクリプトが作れると思います。
関連記事:https://www.otwo.jp/blog/jmeter_study2/
________________________________
執筆者プロフィール:李 嘉興
前職で数年間ソフトウェア開発を経験しました、SHIFTに入社して自動化テストに関する経験が少ない中で毎日楽しんでやっています。更にダイエットしたいと思っても、自分の食欲をコントロールできず、何度も失敗している私です。
【FREE】SHIFTのお役立ち資料
【RECRUIT】まずはお話をしてみませんか?
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/