6

私は一種のオンライン ワークプレイスである Web サイトを開発しています。何人かのユーザーと進行中のコンピューター プログラミング プロジェクトがあり、各ユーザーは複数の役割を持つことができます。たとえば、特定の 1 人のユーザーがプロジェクトのプロジェクト マネージャーと開発者になることができます。別のプロジェクトのために。当然のことながら、プロジェクト マネージャーは、プロジェクトの開発者よりも権限が大きくなります。私の質問は、コードでこれをきちんと管理する方法ですか? カスタム ロール プロバイダーを使用し、これで Authorize 属性を使用するつもりでしたが、特定のプロジェクトでユーザーのロールを見つけるには、プロジェクト ID とユーザー ID が必要になるため、それだけでは十分ではありません。

4

7 に答える 7

6

最初に、拡張ロール管理用の追加テーブルを作成する必要があります。たとえば、 のコンテキストでprojectsとの関係があります。usersoperationscontroller's actions

1 つの方法は、独自のテーブルを作成することですroles。その場合、 Asp net のみを使用しますmembership usersが、それはすべて要件によって異なります。

次に、で処理する必要がありますMVC。私の意見では、独自のカスタムAuthorization属性を使用して実装し、コントローラーのアクションを属性の代わりにカスタム承認属性で装飾するのが最善の方法[Authorization]です。

とてもシンプルです。

[CustomAuthorize]
//[Authorize]
public ActionResult GetProjectTasks(string projectname)
{

}

そのためには、クラスを継承する必要があり、インターフェイスFilterAttributeも実装する必要がありIAuthorizationFilterます。

 public void OnAuthorization(AuthorizationContext filterContext)
    {
        HttpCookie authCookie = filterContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            var identity = new GenericIdentity(authTicket.Name, "Forms");
            var principal = new GenericPrincipal(identity, new string[] { authTicket.UserData });
            filterContext.HttpContext.User = principal;
        }

        var controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
        var action = filterContext.ActionDescriptor.ActionName;
        var user = filterContext.HttpContext.User;
        var ip = filterContext.HttpContext.Request.UserHostAddress;

        var isAccessAllowed = CustomAuthenticationLogic.IsAccessAllowed(controller, action, user, ip);
        if (!isAccessAllowed)
        {
            // Code if user is authenticated
            FormsAuthentication.RedirectToLoginPage();
        }            
    }

メソッドでは、名前、名前OnAuthorizationなどのカスタム認証ロジックで必要になる可能性のあるすべての情報を取得できます。このメソッドからカスタム認証ロジックを呼び出すだけです。カスタム認証ロジックは次のようになります。HttpContextControllerAction

 public class CustomAuthenticationLogic
{
    public static bool IsAccessAllowed(string controller, string action, IPrincipal user, string ip)
    {
        //
        // Your custom logic here              
        //              
    }
} 
于 2012-05-10T12:10:39.070 に答える
4

少し前にいくつかの調査を行ったので、次のことを保証できます。

  1. ASP.NET の組み込み機能はおそらく役に立たないでしょう (プロジェクト ID などを考慮する方法はありません)。
  2. 役割ベースのアクセス モデルが最も適していますが、それを実装するにはさまざまな方法があります。Rusted が提案する AzMan は実際には優れていますが、コンテキスト関連のルールを管理するのは難しい場合があります。例: ユーザー A がプロジェクト C で操作 B を実行しているときに、日曜日としましょう。アズマンを見てください。
  3. アクセス ルールとコードを混在させることは、非常に悪いことです。セキュリティ モデルは、アプリケーションの動作方法 (ASP.NET MVC) に関連付ける必要はないため、これは間違っています。
var isAllowed = AccessControl.IsAccessAllowed(controller, action, user, ip);

次のようになります。

var isAllowed = AccessControl.IsAccessAllowed(user, operation, context);

その後、いつでも好きなときに使用できます。各アクションで、または属性としてラップします。

ここで、操作は「ログイン」、「返信の投稿」、「トピックの読み取り」などです。コンテキストは、「プロジェクト ID」、「曜日」、「ユーザー IP」などのように、それ以外のすべてです。

ロールの重複、コンテキストなど、多くのことを記述することができます。要するに、「.NET ロール ベースのアクセス モデル」に対する Google は、小さなカスタム セキュリティ フレームワークを記述する方が簡単かもしれません。ユーザー、ロール、オペレーション、プロジェクト ID で機能させる

操作はロールに割り当てられ、ロールは定義されたプロジェクト ID を持つユーザーに割り当てられます。操作とロールをハードコーディングできるため、DB では小さな変更が 1 つだけになります: ユーザーからロールへのマッピング

于 2012-05-13T10:54:26.123 に答える
2

AzManの主なアイデアは、操作に対するプログラミングの概念です。

操作は、使用法が重複してはならず、開発者によってのみ定義されるべき非常に細かいものです。操作をタスクにグループ化し、タスクをロールにグループ化してから、プリンシパル (ユーザーとグループ) をロールにマッピングすることで、アプリで承認を定義するための非常に強力なモデルが得られます。操作を直接プログラミングするため、ユーザーが持つ役割をコードで知る必要はなく、実行時に管理者が変更できます。実際、コードで使用する操作を使用するために、まったく異なる一連のロールを誰かが定義することができ、コードをまったく変更する必要はありません。本当の力はそこにある。

「アプリで AzMan を使用する」という意味ではありません (ただし、試してみてください)。これは強力なモデルですが、複雑でもあり、単純なものにはおそらくやり過ぎです。役割が 1 つまたは 2 つしかなく、それらが保護する操作が重複していないか、変更される可能性が低い場合は、おそらく保証されていません。

于 2012-05-06T19:21:44.513 に答える
2

より複雑なルールがあり、属性が十分でない場合は、ユーザーが一部の機能にアクセスできるかどうかをコントローラーで計算し、それらの機能へのアクセスを反映するかどうかを反映する ViewModel のプロパティを追加できます。

このようにして、ビューは非常にスリムになり、それらの ViewModel ブール値プロパティに応じて表示されます。

したがって、ユーザーが読み取りしかできないと想像すると、承認規則に応じてコントローラに入力されるプロパティ bool IsReadOnly を持つことができます。これは、たとえば、テキスト ボックスの代わりにラベルを生成するためにビューで使用されます。

于 2012-05-06T18:38:06.057 に答える
2

groupsに基づいて作成できますroles

次に、別のユーザーを特定のグループに追加します。グループは >

1) Admin Group  
2) Developer Group  
3) Project1-QA Group  
4) Project2-Manager Group

データベースの設計に応じて、[user - group]とのマッピングを保存します。[group - projects]

1 人のユーザーに対して必要な数の役割 (グループ) を持つことができます。

于 2012-05-14T12:21:25.653 に答える
2

インターフェイスを実装する代わりにAuthorize、組み込みフィルターを拡張してカスタム フィルターを作成することをお勧めします。ビルトインは、キャッシュの問題やその他の問題を処理する多くの配管作業を行います。インターフェイスを実装する場合は、それらすべての作業を行う必要があります。AuthorizeAttributeIAuthorizationFilterAuthorizeAttribute

メソッドをオーバーライドするAuthorizeCore必要があり、そこでロール チェック ロジックをすべて実行します。user idセッションに保存する必要project idがあり、それを把握する必要があります。

public override bool AuthorizeCore(HttpContextBase httpContext)
{

}

AuthorizeAttribute ソース コード - http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/913d37658a44#src%2fSystem.Web.Mvc%2fAuthorizeAttribute.cs

カスタム承認属性の例: http://msdn.microsoft.com/en-us/library/ee707357(v=vs.91).aspx

于 2012-05-12T17:12:55.090 に答える
1

非常に単純なアプローチ-サイト全体のアクセス制御の場合、INT列をユーザーテーブルに追加し、そのINTの各ビットを[flags]列挙型にマップできます-たとえば[Flags] enum Access { UpdateProjects, AddProjects }.

プロジェクトごとのアクセス制御の場合、ProjectID (Project テーブルへの外部キー)、UserID (User テーブルへの外部キー)、Role (INT) の 3 つの列を持つ、たとえば ProjectAccessControl という名前のテーブルを作成します。Role 列は INT であり、その各ビットは異なるブール値フラグを意味する必要があり (前の例のように、これを C# の列挙型にマップできます)、最初のビットがオンの場合、ユーザーは説明を更新する権利を持っていると言えます。 2 番目のビットがオンの場合、ユーザーはスケジュールなどを変更できます。

[Flags]
enum ProjectAccessRole
{
    UpdateDescription,
    ChangeSchedule,
    etc...
}

コードでは、ユーザーの役割がスケジュールを更新する権利を持っているかどうかを次の方法でテストできます。

if( (intUserRole & ProjectAccessRole.ChangeSchedule) 
     == ProjectAccessRole.ChangeSchedule)
{
    /*user has right*/
}

次に、このチェックを 2 つのパラメーターを取る単純な関数にラップできます。次に、 を呼び出すだけHasRights(intUserRole, ProjectAccessRole.ChangeSchedule);です。

于 2012-05-15T17:06:33.737 に答える