Gatlingで複雑な認証システム(SAMLやCSRFトークンなど)の負荷テストを簡単に!!

こんにちは、サイオステクノロジー武井です。今回は、SAMLをベースとした認証システムや、CSRFトークンが必須なWebアプリケーションの負荷テストを簡単にするツール「Gatling」の使い方と実践的なスクリプトをご紹介します。

Gatlingとは?

Webアプリケーションへの負荷テストツールです。同じようなものにJMeterがありますが、Gatlingの最大のメリットは、ScalaベースのDSLによって、シナリオを作成できるということです。

単純なシナリオであれば、わざわざDSLによって定義することはありません。JMeterにも、JMeter自身をプロキシとすることによって、Webブラウザでの操作をそのままシナリオに落とし込める方法が存在します。

ただし、複雑なシナリオの場合にはそのようにはいきません。例えば、不正なアクセスを防ぐ仕組みであるCSRFトークンは、Webアプリケーションへの、ある画面へのアクセスごとに任意のトークンを画面に埋め込みます。アクセスする際は、その画面に埋め込まれたトークンをサーバーに送出、サーバー側でそのトークンの有効性を確認します。

このCSRFトークンを負荷テストのシナリオで再現するためには、画面に埋め込まれたトークンを抽出する必要はあります。例えばCSRFトークンが<input type=”hidden” name=”tokne” value=”XXX”>のように埋め込まれていた場合は、正規表現か何かで、XXXを抽出しなければなりません。

また、SAMLの認証のシナリオにおいても同様です。SAML Responseを送出する方法として、Post Bindingが採用されていた場合、IdP側で認証が成功すると、そのHTTPレスポンスにSAML ResponseをJava ScriptのOnLoadでPostするようなHTMLが返ってきます。この場合も、正規表現か何かで、HTMLからSAML Responseを抽出しなければいけません。

このように、認証のような複雑なシナリオでは、HTTPレスポンスを解析して必要な値を抽出するという複雑な処理が必要になります。このようなときには、やはりDSLでシナリオを記述できるGatlingがラクチンです。JMeterでもできなくはないですが、あのXMLの設定で複雑なシナリオを実現するのはJMeterの独自仕様を理解しなければいけないので骨が折れます。Gatlingであれば、多少Scalaの知識があれば、Scalaのコーディング技法で、シナリオを自由に定義することができます。

では、様々なユースケースごとにGatlingの素晴らしをご紹介していきたいと思います。

インストール

何はともあれ、まずはインストールです。GatlingはScalaで記述しますので、Javaがインストールされていることが前提となります。

以下のURLにアクセスして、「DOWNLOAD NOW! 」をクリックして、Gatling本体をダウンロードします。

https://gatling.io/open-source

Gatlingを任意のディレクトリに解凍して配置すればインストールは環境です。以下の例では、/opt/gatlingというディレクトリに配置する例です。

ユースケースその1:簡単な負荷テストをする

まずは超簡単な負荷テストを実施してみたいと思います。シナリオは以下とします。

  • http://hoge.example.com/というURLに対して、同時10接続でアクセスする。MethodはGETとする。

 

上記のシナリオは以下のように定義します。

 

このシナリオを実行します。シナリオのファイルを/opt/gatling/user-files/simulationsディレクトリに配置します。

 

実行します。

 

以下のように結果が出力されます。

 

request countのKOが0であれば、全てのリクエストは成功しています。OKが成功、KOが失敗を表しています。

ユースケースその2:フォームに入力した値をPostするケース

次に、フォームに入力した値をPostするようなケースを考えてみます。ログイン画面でIDとパスワードを入力して送信するというのがよくある例ですね。以下のようなシナリオを考えてみます。

  • ログイン画面はhttp://hoge.example.comというURLとする。
  • ユーザー名のパラメータ名はusername、パスワードのパラメータ名はpasswordとする。
  • http://hoge.example.com/loginというURLに対して、ユーザー名とパスワードをPostする。
  • Content-Typeはapplication/x-www-form-urlencodedとする。
  • 上記のシナリオを同時10接続で実施する。

 

上記のシナリオは以下のように定義します。

 

実行方法は、ユースケースその1と同じですので割愛します。

ユースケースその3:CSRFトークンを送出するケース

だんだん複雑になってきます。CSRFトークンを送出するケースを考えてみます。以下のようなシナリオを考えてみます。ユースケースその2にCSRFトークンを送出する処理を追加しました。

  • ログイン画面はhttp://hoge.example.comというURLとする。
  • ユーザー名のパラメータ名はusername、パスワードのパラメータ名はpasswordとする。
  • ログイン画面にはCSRFトークンが、<input type=”hidden” name=”tokne” value=”XXX”>のように埋め込んである。
  • http://hoge.example.com/loginというURLに対して、ユーザー名とパスワードをPostする。
  • Content-Typeはapplication/x-www-form-urlencodedとする。
  • 上記のシナリオを同時10接続で実施する。

 

上記のシナリオは以下のように定義します。

 

実行方法は、ユースケースその1と同じですので割愛します。

ユースケースその4:SAMLに対応したIdPに負荷をかけるケース

最後はSAMLに対応したIdPに負荷をかけるケースを考えてみます。シナリオは以下のようになります。

  • SAMLに対応したIdP(以降、IdPと呼称)のURLはidp.exmaple.comとする。
  • IdPは正しいユーザー名とパスワードを入力すれば認証は完了とする。
  • SAMLに対応したSP(以降、SPと呼称)のURLはsp.exmaple.comとする。
  • SPの仕様はHTTPレスポンスとして、IdPに入力したユーザー名がそのまま返ってくるものとする。
  • SPにSAML Responseを返す方法は、Post bindingsとする。
  • Post BindigsでSAML Responseを返す際、SAML Responseのパラメータ名はSAMLResponse、Relay Stateのパラメータ名はRelayStateとする。
  • IdPに入力するユーザー名はusers.csvに以下のように定義し、上から順番にIdPにPostするものとする。

     

上記のシナリオは以下のように定義します。

 

実行方法は、ユースケースその1と同じですので割愛します。

まとめ

いかがでしたでしょうか?ScalaによるDSLでシナリオを定義するGatlingであれば、認証システムへの負荷テストも簡単に実現できますね!!もうGatlingなしでは生きていけません。No Gatling, No Life!!





ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!


ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメント投稿

メールアドレスは表示されません。


*