こんにちは。今日は、大規模なサービスサイトのサポートを利用したかなり便利な手法について説明します。 つまり、パスワードなしで普通のユーザーとしてサイトにアクセスする機能(データベースにパスワードをクリアテキストで保存しないのですか?)
はじめに
既に準備ができており、稼働中の活気のあるWebサイトがあるとします。 そして、たとえば、ロール、セキュリティポリシー、およびその他のビジネスロジックに応じて、ユーザーごとに外観や動作が異なることがありました。 簡単にするために、インターネットバンキングを利用しましょう。
挑戦する
管理者または技術サポートオペレーターなどが特定のユーザーとしてログインできるようにします。 たとえば、コールセンターにダイヤルしたユーザーに、サイトを目で見て問題の解決策を説明する方がはるかに簡単です。
解決策
ASP.NET MVCを例に取り上げますが、ドル記号や宝石のファンは、お気に入りのフレームワークに似たものを実装できないはずです。 コードを強く叩かないでください-それは例として4年前に書かれました。
Windows認証の世界には、 偽装と呼ばれる既成の美しいソリューションがあります。 つまり あるユーザーが別のユーザーのふりをして、自分の権利と、自分に代わってアクションを実行する能力を取得する。
すべては問題ありません。架空のインターネットバンキングのみがフォーム認証を使用しています。 <authentication mode = "Forms"のようなものがweb.configに書き込まれます(専用ではない場合:ログインは、ログインとパスワードを入力するための通常のWebフォームとして実装されます)。 このモードでは、偽装パンの使用は機能しませんが、このようなものを実装しようとすることができます。
まず、次のメソッドをAccountController.cs(デフォルトのASP.NET MVCプロジェクトで作成)に追加します。
public ActionResult Impersonate(string user) { //checking if user is logged in if (Request.IsAuthenticated) { //and checking if he is a super user if (Roles.IsUserInRole("admins")) { //saving current auth cookie for a later use HttpCookie cookie = Request.Cookies[FormsAuthentication.FormsCookieName]; cookie.Name = "__" + cookie.Name; Response.Cookies.Add(cookie); //logging out for current user FormsAuthentication.SignOut(); //making new user logged in without a password FormsAuthentication.SetAuthCookie(user, true); //redirect to some page here return RedirectToAction("Index", "Home"); } } //currently logged user has no rights to impersonate throw new SecurityException(); }
全体のポイントは、現在のユーザーを別の名前でログインし、パスワードをチェックせずに管理者ロール(または、たとえば「レベル3テクニカルサポートオペレーター」)に入るかどうかをチェックすることです。 これを行うために、新しい対応する認証Cookieを彼に渡し、パスワードを再入力せずに管理者モードに戻ることができるように古いものの名前を変更します。
手順では、次のようになります。
- ユーザーがログインしているかどうかを確認します
- 彼が他の誰かになりすますふりをするのに十分な権利を持っているかどうか確認してください
- 現在のセッションCookieを別の名前で保存します
- パスワードを確認した後(Membership.ValidateUser()の後)に通常のログインで行うのと同じように、別のユーザー用に新しいパスワードを作成します
- たとえば、メインページにリダイレクトする
その結果、ブラウザはすでに2つのCookieを受信し、サーバーは現在のセッションを通常のユーザーセッションとして認識します。
新しく作成したメソッドを呼び出すには、ユーザーのリストを含む新しいページが必要です。 完全なリストは提供しません。アイデアは明確だと思います。
using (Html.BeginForm("Impersonate", "Account")) { var users = Membership.GetAllUsers(); // or Roles.GetUsersInRole(...) foreach (var userName in users) { ... } }
全体として、必要なユーザーを選択した後、管理者は一時的に通常のユーザーになります。
管理者モードに戻る機能を追加するだけです。 新しい要素を追加してサイトの外観を変更したくないので、既存の終了ボタンを使用します。 これを行うには、(AccountController.cs内の)既存のexitメソッドをわずかに拡張します。
public ActionResult LogOff() { //checking if we impersonated already HttpCookie cookie = Request.Cookies["__" + FormsAuthentication.FormsCookieName]; if (null != cookie) { //logging off FormsAuthentication.SignOut(); //restoring original auth cookie of a super user cookie.Name = FormsAuthentication.FormsCookieName; Response.Cookies.Add(cookie); //removing previosly saved auth cookie of a super user so we can logout normaly next time HttpCookie expired = new HttpCookie("__" + FormsAuthentication.FormsCookieName); expired.Expires = DateTime.Now.AddDays(-1); Response.Cookies.Add(expired); } else { //logging off in a ordinary fashion FormsAuth.SignOut(); } //redirecting return RedirectToAction("Index", "Home"); }
最初に、以前に保存された管理者Cookieが存在するかどうかを確認します。 その場合、名前を元に戻しますが、一般ユーザーのことは忘れてください。 その結果、終了ボタンを押すと、管理者は通常の環境に戻ります。 そして、再び終了ボタンをクリックすると、完全にログアウトします。
最終結果
サイト管理者にログインします
なりたいユーザーを選択する
サイトは、私たちが通常のユーザーであると考えています
ブラウザで保存されたCookieを見ると、両方のトークンを見ることができます
ログオフをクリックした後、管理者モードに戻ります
したがって、Cookieは復元されます
もう一度[ログオフ]をクリックすると、完全に終了します
おわりに
最小限の変更を加えた合計で、しばらくの間、別のユーザーのふりをする機能を追加しました。 さらに、サイトの外観やロジックを変更することさえありません。 Webアプリケーションの残りの部分では、そのような操作は完全に透過的であり、何も壊さないはずです。
だれでもふりをすることができる人の論理について考えるだけです。 たとえば、これらのサポートのオペレーターは管理者としてログインできませんでした。
誰かが他の方法で同様のスキームをすでに実装しているかどうかを知ることは興味深いですか? コメントを購読解除します。