1

私たちのMVCプロジェクトでは、すべてを可能な限り一般的にしようとしています。

このため、すべてのメソッドをカバーする1つの認証クラス/メソッドが必要です。

例として:次のコードは、クライアントから呼び出すことができるMVCクラスです。

public class Test
{
    public void Test()
    {
    } 

    public int Test2(int i)
    {
         return i
    }

    public void Test3(string i)
    {
    }
}

Webサービスのお客様は、サービス参照を使用してTest()、Test2()、およびTest3()にアクセスできます。

[PrincipalPermission]現在、クラス、モデル、インターフェイスなど、メソッドへのアクセスを変更したり(現在属性を使用している)、パラメーター値を変更したりするために使用できるものを探しています。

例:

お客様Aから電話がありますTest2(150)

クラス/メソッドは、顧客AがにアクセスできるかどうかをチェックしますTest2。クラス/メソッドはユーザーを検証しますが、ユーザーがにアクセスできないことに気づきます150。彼はにアクセスすることしかでき100ません。そのため、クラス/メソッドはパラメータをに設定し、その過程を100たどることができます。

CustomberBクラスTest()

クラス/メソッドは、顧客BがにアクセスできるかどうかをチェックしますTest。検証後、ユーザーにアクセス権がないことが示されるため、SecurityExceptionがスローされます。

私の質問:

どのクラス、インターフェース、属性、またはこれを行うのに最適なものは何ですか?

(ps。例として、私は認証とパラメーター処理のみを使用しましたが、この段階ではさらに多くのことを行う予定です。)

編集

すべてではないにしても、ほとんどの場合、actionResultsを使用していると想定しています。したがって、これは、データベースからの情報をお客様に提供するWebサービスで使用されていることを述べたいと思います。Webサービスへのリクエスト中にActionResultと接触することは決してありません。(少なくとも、お客様ではありません)

4

7 に答える 7

3

認証は、アスペクトを介して行うこともできます。アスペクト指向パラダイムは、これらのいわゆる横断的関心事を尊重するように設計されています。「昔ながらの」oo-wayに実装された横断的関心事は、コードに「直接的な」利点をもたらさないため、ビジネスロジックを読みにくくするか(上記のニックの例のように)、さらに理解しにくくします。

public ActionResult YourAction(int id) {
  if (!CustomerCanAccess(id)) {
    return new HttpUnauthorizedResult();
  }

  /* the rest of your code */
}

ここで必要なのはそれだけです/* the rest of your code */

たとえば、ロギング、例外処理、キャッシング、承認などの機能は、アスペクトとして実装できるため、1つのポイントで維持できます。

PostSharpは、アスペクト指向のC#フレームワークの例です。PostSharpを使用すると、カスタムアスペクトを作成してから、メソッドに注釈を付けることができます(で行ったようにPrincipalPermissionAttribute)。PostSharpは、コンパイル中にアスペクトコードをコードに織り込みますPostSharpアスペクトを使用すると、呼び出し元のユーザーを認証するメソッド呼び出しにフックしたり、メソッドパラメーターを変更したり、カスタム例外をスローしたりすることができます(これがどのように実装されるかについては、このブログ投稿を参照してください)。

于 2013-03-31T18:31:15.660 に答える
1

このシナリオを処理する組み込みの属性はありません。

私は通常、次のようなことをするのが最善だと思います。

public ActionResult YourAction(int id) {
  if (!CustomerCanAccess(id)) {
    return new HttpUnauthorizedResult();
  }

  /* the rest of your code */
}

これは、簡単に拡張できます。多くの場合、これで十分です。また、セキュリティアサーションをテスト可能に保ちます。メソッドを(MVC配管なしで)呼び出すだけで、呼び出し元が承認されているかどうかを確認する単体テストを作成できます。

ASP.Netフォーム認証を使用している場合は、以下も追加する必要があることに注意してください。

Response.SuppressFormsAuthenticationRedirect = true;

ユーザーが許可されていないリソースにアクセスしようとしたときに、ユーザーがログインページにリダイレクトされないようにする場合。

于 2013-03-29T13:39:45.677 に答える
0

これが私の人生をよりシンプルにした方法です。

  1. アクション引数に単純な値を使用しないでください。アクション引数を表すクラスを常に作成してください。値が1つしかない場合でも。私は通常、このクラスを再利用できるようになることがわかりました。
  2. このクラスのすべてのプロパティがnull許容であり(これにより、デフォルト値(整数の場合は0)が自動的に入力されないようにします)、許容範囲が定義されていることを確認します(これにより、負の数について心配する必要がなくなります)
  3. 引数を表すクラスを作成したら、プロパティにバリデーターをスローするのは簡単です。

重要なのは、意味のないintを渡していないということです。これには目的があり、製品番号、アカウント番号などがあります。それをプロパティとして持つクラスを作成します(たとえば、'idと呼ばれる単一のフィールドを持つAccountIdentifierクラス)。次に、[CurrentUsedCanAccessAccountId]属性を作成し、そのプロパティに配置するだけです。

コントローラが行う必要があるのは、ModelState.IsValidであるかどうかを確認することだけです。

ユーザーがパラメーターの特定の値にアクセスできるかどうかに基づいて自動的にリダイレクトするアクションフィルターをメソッドに追加するなど、より洗練されたソリューションがありますが、これはかなりうまく機能します

于 2013-03-25T12:59:55.557 に答える
0

まず、それを言うだけで、それyour own methods are probably the most appropriate place to handle input values (adjust/discard) - and with the addition of Authorize and custom filter actions you can get most done, and the 'MVC way'。また、「OOの方法」で、ITestインターフェイスやディスパッチャなどを使用することもできます(コンパイラのサポートが増えますが、より結合されます)。ただし、もっと複雑なものが必要だと仮定しましょう...

また、あなたTestがコントローラーであると想定しています。そうでない場合でも、MVCを念頭に置いて(またはMVCの機能を模倣することで)「パイプライン」の一部にすることができます...

明らかな解決策の1つは、独自のカスタム属性を作成してオーバーライドするなどして、 ActionFilterAttributeクラス (Authorizeなど)を介してフィルターまたはアクションフィルターを適用すること です。OnActionExecuting

それは問題ありませんparameters manipulationが、コードを「アウトオブプレース」で指定する必要があるため、または何らかの方法で各属性にデリゲート、ラムダ式を挿入する必要があるため、あまり役に立ちません。

それは基本的an interceptorにあなたが必要とするある種のものです-それはあなたがあなた自身の処理を添付することを可能にします。私は似たようなことをしましたが、この男は解決策を説明して実装するのに素晴らしい仕事をしました。そのため、私がそのほとんどを繰り返す代わりに、それを読むことをお勧めします。

インターセプターパターンを使用したASP.NETMVCコントローラーアクション(Amarによると思います)

これは、フィルターに既存のMVCメカニズムを使用することですが、別の「インターフェイス」を介して公開します。入力の処理ははるかに簡単だと思います。基本的に、あなたがすることは次のようなものです...

[ActionInterceptor(InterceptionOrder.Before, typeof(TestController), "Test1")]
public void OnTest1(InterceptorParasDictionary<string, object> paras, object result)

パラメータと変更は伝播されますcontext。ある種のものがあるので、それ以上の実行を終了できます。または、両方のメソッドに作業を任せることができます。

また興味深いのは、パターン全体(一種のIOC)であり、別のクラス/コントローラーでインターセプトコードをまとめて定義するため、独自のテストメソッドを「装飾」する代わりに、属性とほとんどの作業が外部に配置されます。

そして、パラメータを変更するには、次のようなことを行います...

// I'd create/wrap my own User and make this w/ more support interfaces etc.
if (paras.Count > 0 && Context.User...) 
{
    (paras["id"] as int) = 100;
}            

そして、手元にある自分のケースの実装をさらに変更できると思います。

これは大まかな設計です-そこにあるコードが本番環境の準備ができているかどうかはわかりませんが(MVC3用ですが、同じではない場合は似ています)、十分に単純化されており(説明した場合)、若干の調整を加えるだけで問題なく動作するはずです。あなたの側。

于 2013-03-31T13:44:19.050 に答える
0

あなたの質問を理解したかどうかはわかりませんが、モデルバインダーが役立つようです。

モデルバインダーには、ユーザーがメソッドに対する権限を持っているかどうかを判断するためのインターフェイスを挿入できます。必要な場合は、パラメーターとして提供されている値を変更できます。

インターフェイスを実装するValueProvidersIValueProviderも、この場合に役立つ場合があります。

于 2013-03-31T15:48:12.693 に答える
0

あなたが十分な答えを得られなかった理由は、あなたの質問にいくつかの曖昧さがあったからだと思います。まず、クライアントから呼び出されたMVCクラスがあると言いますが、ActionResultsはないと言います。したがって、asp.net mvcフレームワーク、Web api、wcfサービス、またはsoap(asmx)Webサービスのいずれを使用しているかを明確にすることをお勧めします。私の仮定が正しく、asp.net mvcフレームワークを使用している場合、アクションの結果を使用せずにWebサービスをどのように定義し、クライアントはこのサービスをどのように「呼び出す」のでしょうか。私はそれが不可能だとか、あなたがしたかもしれないことが間違っていると言っているのではありませんが、もう少し明確さ(そしてコード)が役立つでしょう。

asp.net mvc3を使用している場合の私のアドバイスは、コントローラーとアクションを使用してWebサービスを作成するように設計することです。あなたがする必要があるのは、Json、xml、またはクライアントがアクション結果で期待するその他のものを返すことだけです。

これを行った場合は、質問に投稿したクラスとよく似たクラスにビジネスロジックを実装することをお勧めします。このクラスは、認証またはアクセスレベルの要件についての知識がなく、必要なビジネスロジックの実装と正しい結果の生成にのみ集中する必要があります。

次に、アクションパラメータを検査し、呼び出し元が実際にメソッドにアクセスすることを認証および許可されているかどうかを判断できる、アクションメソッドのカスタムアクションフィルタを作成できます。カスタムアクションフィルターの作成方法については、こちらをご覧ください。

これがあなたの望むもののように聞こえ、私の仮定が正しいと思われる場合は、私に知らせてください。私が上で説明したことをキャプチャするためのコードを投稿させていただきます。私が正直に進んだ場合は、質問を明確にしてください。解決策の提案に一歩近づく可能性があります。

psAOPの「考え方」が必要です。AOPツールとしてのPostSharpは素晴らしいですが、わずかに異なるアーキテクチャとasp.net mvcの機能の適切な使用では達成できない、postsharpがここで行うことはないと思います。

于 2013-04-03T16:58:08.767 に答える
0

最初にActionFilterAttribute(system.web.mvc)から継承して属性を作成し、次にOnActionExecutingメソッドをオーバーライドして、ユーザーに権限があるかどうかを確認します

この例

    public class CheckLoginAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Membership.IslogedIn)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
                                {
                                   { "area",""},
                                   { "action", "login" },
                                   { "controller", "user" },
                                   { "redirecturl",filterContext.RequestContext.HttpContext.Request.RawUrl}
                               });
        }
    }
}

次に、ユーザー権限を確認する必要があるすべてのメソッドにこの属性を使用します

public class Test
{
    [ChecklLogin]
    public void Test()
    {
    } 
    [ChecklLogin]
    public int Test2(int i)
    {
         return i
    }
    [ChecklLogin]
    public void Test3(string i)
    {
    }
}
于 2013-04-03T17:11:51.183 に答える