2016-07-15 3 views
2

コントローラの多くの動作に再現される次のコードブロックを考えてみましょう。 (私は主にメソッド本体の最初の6行に関係しています)。ASP.NET MVC - オプションでベースクラスメソッドからリダイレクトしますか?

[HttpGet] 
public ActionResult OptOut() 
{ 
    var user = this.SecurityPrincipal; 
    if (user.IsReadOnlyUser) 
    { 
     this.TempData["ViewModel"] = new AuthorizationModel { User = user }; 
     return this.RedirectToAction("NotAuthorized", "Authorization"); 
    } 

    var model = /* Elided for brevity */ 

    return this.View(model); 
} 

私のコントローラは、今度は、Controllerから派生基本クラスから派生SecuredControllerSecurityPrincipalは、SecuredControllerのプロパティであり、現在のユーザーに関する広範なActive Directoryデータを含んでいます。

重複したコードを削除するために、if {...}ブロックに含まれる機能を基本クラスのメソッドに移動するのが理想的ですが、これを行う方法は考えられません。この方法は、このような不格好なもので、その結果、ActionResultでなければならないであろう。

if ((var result = this.RequireReadWrite()) != null) 
{ 
    return result; 
} 

誰もがこれを行う方法を提案、または私はここで、単純に運が悪いだことはできますか?

+5

[MVCアクションフィルタ](http://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/)についてはどうすればよいですか?理解 - 行動 - フィルター - CS)?あなたのデザインでそれを考えましたか? 'ActionResult'の内容に' filterContext'を追加することでより多くの制御ができます。 – QuantumHive

+1

Aフィルター音が適切です。 – Shyju

+4

一般に、あなたのメソッドでセキュリティを行っているなら、それは間違っています。セキュリティはクロスカッティングの問題であり、メソッドを実行する前に処理する必要があります。前述したように、これを処理するにはフィルターが適していますが、MVCにはフレームワーク全体があります。自分のセキュリティをロールしようとしていますが、それはほとんど常にアンチパターンです。本質的に、あなたはあなたの家に高価で十分にテストされたセキュリティシステムを持っており、ドアを開けずに退屈な10代の人に家が安全であることを確認するように求めています。 –

答えて

2

コメントに記載されているように、特にセキュリティがcross cutting concernであることに注意して、MVC Action Filtersを使用してユースケースとデザインに適用することを提案しました。
マイクロソフトの文書は非常に有益であり、Web上で使用方法の詳細については、MVCフィルタの例があります。私は例を挙げようとしますが、これはソフトウェアアーキテクチャーに関する多くの前提に基づいています。なぜなら、私は単にその知識がないからです。 Dependency Injectionフレームワークを使用して、あなたはSecurityPrincipalサービスを注入することができれば

public class SecuredFilterAttribute : AuthorizeAttribute 
{ 
    ... 
} 

は、次のようなクラスを作成することができます。しかし、私はあなたのアプリケーションのアーキテクチャを知らないので、その依存関係をどのように作成するかはあなた次第です。

protected override bool AuthorizeCore(HttpContextBase httpContext) 
{ 
    return !this.SecurityPrinciple.IsReadOnlyUser; 
} 

をオーバライド許可されていないときHandleUnauthorizedRequest方法はリダイレクトする:
AuthorizeCoreをオーバーライドするときは、そのようにそれを実装することができ

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) 
{ 
    var redirectRoute = ...; //your route to redirect to an unauthorized page 
    filterContext.Result = new RedirectToRouteResult(redirectRoute); 
    //do some other things, for example, setting some tempdata information 
} 

ここでも、それはあなたがこれを使用する方法にあなた次第ですがフィルター。あなたはそれをグローバルに登録したり、コントローラーやアクションごとにそれを適用することができます。

GlobalFilters.Filters.Add(new SecuredFilterAttribute()); 
+1

DIコンテナとして[SimpleInjector](https://simpleinjector.org/index.html)を強くお勧めします。 – QuantumHive

+0

ありがとうございました。これはほぼ正確に私がやったことでした、そして、それは完全に動作します。これはほんのわずかのアクションメソッドで必要なので、グローバルハンドラを登録するのではなく、それらのメソッドを属性で修飾することにしました。もう一度、ありがとう! –

関連する問題