私の仕事では、サイトとコントロールのセクションへのアクセス権の分離の問題に頻繁に直面しています。
最初は、ASP MVCがすぐに使用できる十分なツールがありましたが、時間が経つにつれて、独自の権利共有ツールを作成する必要に直面しました。 親愛なる%habrauser%がこの問題を解決する方法に興味があるなら、catにようこそ。
いくつかの歌詞
プロジェクトの1つで、サイトのセクションと要素へのアクセス権を共有する問題に遭遇しました。 これは、従業員が休暇を計画できる会社の内部Webサイトです。 TKは驚くほどうまく書かれています。 作業は加速ペースで進み、1か月の作業の後、作業用プロトタイプの準備が整いました。 システムの運用に関する「洗練」が開始されなかった瞬間まで、誰もがまさに喜んでいました。 そして、官僚は誕生以来私たちの男性に座っていたので、多くの調整と議論がありました。その結果は次のようなものでした。 しかし、これは普通のユーザーには見られないはずです。 そして、これは管理者のみが見ることができます。 そして、これは特に秘密の管理者だけが見るべきであり、他の誰も見るべきではありません!」 そして、残念なことに、これは顧客の混乱した想像力の終わりではありません。
標準ツールを使用して役割とアクセスの管理を行うことができますが、非常に面倒です。 そのため、簡単に管理できるアクセス共有モジュールの作成に取りかかりました。
はじめに
まず、モジュールの基本的な要件が導き出されました。
- コントローラメソッドへのアクセス権の簡単な分離(Authorize属性の原理に基づく)
- サイト要素へのアクセスを共有するための使いやすいメカニズム
- アクセスバリエーションのあるロールを作成する機能
- さまざまなプロジェクトで使用する能力
その後、さまざまなスキームを作成し、トピックに関する膨大な資料を表示する「作業」を実施しました。 その結果、モジュールの概念が開発されました。
モジュールが機能するために必要なデータは、MSSQLデータベースに格納されます(c#で記述した場合は、他のものに格納されます)。 企業ネットワーク構造の特性と、プロジェクトで(理論上)を使用するというアイデアのために、私は集中ストレージを行いませんでした。 したがって、モジュールデータのセットをプロジェクトデータベースに書き込みます。
また、モジュールはどのプロジェクトでも機能するという考えに基づいて、モジュールが接続されているプロジェクトのweb.configファイルから設定を読み取る必要があります。
さて、新しいプロジェクトへの展開が... ahemと同じくらい簡単になるように、モジュールにベースを準備し、初期構成を行う方法を教えてください。 さて、あなたはポイントを得る。
また、デフォルトで、新しく作成または追加されたすべての要素とセクションをテーブルに入力し、「スーパー管理者」にアクセスできるようにして、作業するたびに設定を行う必要がないようにします。
はじめに
最初に、結果のモジュールについて少し説明したいと思います。 彼の仕事では、彼は自分で書いたRoleProviderを使用します。 また、その使用の理由は、企業ネットワークの機能でした。 したがって、サーバーの1つに、従業員に関するすべてのデータとドメインログインへのバインドが格納されているディレクトリが作成されました。 理由を聞かないでください。 これは確立された状態です。
そのため、ディレクトリの内部ニーズのために、従業員のグループがあります。 そのため、主要な機能を実行するだけでなく、サーバー上のディレクトリ内のグループを操作する役割プロバイダーが作成されました。 それは特別な興味の対象ではなく、プロバイダーを書く上で新しいものを見つけることはないので、私はそれを持ち込みません。 (コードスニペットでは、ロールプロバイダーを含むAuthLib名前空間にアピールします)。
コードが実行されるまで、コード内のコメントやその他のゴミについて謝罪したいと思います。 与えられたコードは(現在のプロジェクトの現実では)時代遅れであり、アイデアを示すためだけに与えられています。最初のステップは、ユーザーを記述するクラスを作成することです。 将来は働きやすくなります。
クラス「従業員」using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.SqlClient; namespace Ekzo.BaseClasses { public class Employee : IEquatable<Employee> {
次に、システムの要素(セクション、リンク、コントロールなど)を記述するクラスを準備します
クラス「アクション」 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; namespace Ekzo.Web.Security.Utilization.Authorization {
クラス「アクショングループ」 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Ekzo.Web.Security.Utilization.Authorization {
クラス「コントロール」 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Ekzo.Web.Security.Utilization.Authorization {
クラス「コントロールグループ」 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Ekzo.Web.Security.Utilization.Authorization {
クラス「コントロールとロールのリンクグループ」 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Ekzo.Web.Security.Utilization.Authorization {
クラス「システムロール」 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; namespace Ekzo.Web.Security.Utilization.Authorization {
次に、承認属性(AuthorizeAttribute)から継承された属性の実装に移ります。これは、コントローラーのメソッドに適用され、現在のユーザーがサイトのページにアクセスする権利を持っているかどうかを判断します(ここでは、言い回しは少し間違っていますが、理解を簡単にするためにそのままにしておきます)。認可属性 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Ekzo.Web.Security.Utilization {
実装に複雑なものはありません。 AuthorizeCore関数を再定義します。これは、ユーザーにアクセスする権利がある場合、または管理者が設定で認証を無効にしている場合にtrueを返します。ユーザーにアクセス権がない場合は、falseを返し、401エラーページにリダイレクトします。注意を引くのは、次の行のみです。 if (!currentAction.IsExist()) currentAction.Save();
これにより、テスト対象のメソッドのルールの存在が確認されます。ルールがない場合は作成します。これは、新しいメソッドのルールを追加するのではなく、自動的に追加するために行われました(今後、管理者の承認ルールの作成は内部で行われるため、適切な権限を持つすべてのユーザーがアクセスできるようになります)。ビューだけでなく、最も頻繁に使用される標準型の拡張機能を作成することは残っています。拡張機能 using System; using System.Linq; using System.Web; using System.Web.Mvc; namespace Ekzo.Web.Security {
これが、権利分離システムの作業に必要なすべてです。コントローラーでの応用例 [ActionAuthorization(ActionName = " ")] public ActionResult RequestsInWork() { ViewBag.Title = " "; return View(); }
制御アプリケーションの例 ... @Html.MainMenu().HasControlAccess(" ") ...
解説
ここで、前述のすべてのさの意味を明らかにしようとします。まず、作成された構造により、コントローラーのメソッドだけでなく、サイトのページ上の他の「任意の」要素も制御できます。次に、ユーザーの役割-「オブジェクトのグループ」-「保護されたオブジェクト」の関連付けを任意の構成で実行できるモジュールインフラストラクチャが用意されています。つまり、任意のユーザーが任意のロールに所属できます。役割は、保護オブジェクトの任意のグループに結び付けることができます。オブジェクトは任意のロールに含めることができます。このような華やかな束を使用すると、保護されたオブジェクトと、それらが使用可能なロールの組み合わせを作成できます。したがって、新しい役割が表示されると、システム内の別の役割に既に割り当てられている権利を発行することも、一意の権利セットを発行することもできます。顧客が来て「私は新しい役割が欲しい、そういう人が利用できるようになりたい」と言ったら、それはすべてプロジェクトコードの変更を必要としない簡単なアクションを実行することになります。モジュールで作成された拡張機能により、たとえばHtmlHelper独自のメソッドで出力データを柔軟に制御することもできます。実際には、権利を共有するこの方法は、AJAXリクエストでうまく機能します。ちょっとしたグッズ
より便利な管理のために、クラスコンフィギュレーターを作成しますコンフィギュレーター using System; using System.Collections.Generic; using System.Data.SqlClient; using log4net; namespace Ekzo.Web { public static class Configuration {
このクラスには、すべての設定と、ボーナスとして、モジュールテーブルの管理に必要な機能が含まれています。GitHubプロジェクト結論の代わりに
私が説明したEmployeeクラスは省略してもかまいませんが、私のプロジェクトではよく使用するため、モジュールから削除しませんでした。役割とバインディングをすばやく/便利に作成/削除/変更できるようにする役割管理用のインターフェイスが作成されました。しかし、モジュールの新しいバージョンで動作するため、アップロードしません。もう一度、トマトを投げないでください。上記のコードとGitHubにあるプロジェクトはすべて最初のバージョンであり、大量のgovnokodが含まれています。