2016-05-26 24 views
0

MVCで単純な「hello world」をコンセプトとして作成しました。インデックスビューリストには、一般的な「編集」、「詳細」、「削除」アクションリンクが続くレコードがあります。ASP.NET MVCで直接URLを使用できないようにする

ただし、レコードを所有するADグループによっては、これらのオプションの一部をレンダリングしません。たとえば、私が5レコードを引っ張っているとしたら、私はそのうちの1つのみを所有するGroup \ Roleのメンバーです。ようになり、私のインデックスページ...

名前価格
FOO1 $ 10.00詳細
foo2は$ 20.00詳細
Foo3 $ 30.00詳細|編集|このすべてが素晴らしい作品
Foo4 $ 40.00詳細
Foo5 $ 50.00詳細
Foo6 $ 60.00詳細

を削除します。問題は、ユーザーとして、/ Home/Edit/Foo1のURLを入力するだけで、私が所有していないレコードへの編集アクセスが可能になるということです。

最初の検索では、ChildActionOnly属性と呼ばれるものを実装するはずです。私が何を読んでから、それは

[ChildActionOnly] 
public ActionResult Edit(string id) 
{ 
    return View(GetItem(id)); 
} 

が、それは私が私のURLを変更し、そこに到達することができません..私のコントローラに設定された場合のように聞こえます。しかし、その属性を追加する瞬間、アクションリンクはもはや機能しません。

@Html.ActionLink("Edit", "Edit", new { id = item.FooName }) 

私はちょうど何かが足りないと知っています。私はすでに認証を実装しています。あなたが正しい役割に属していない限り、そのコントローラへのすべてのアクセスを既にブロックしています。しかし、一度アクセスすれば...何かを変更するアクセス権があるわけではありません。文書によると

答えて

0

ChildActionOnlyAttribute Class

はアクションメソッドが唯一の子のアクションと呼ばれるべきであることを示すために使用される属性を表します。

子アクションメソッドではなく、全体のビューをレンダリングするビュー の一部のインラインHTMLマークアップをレンダリングします。

ChildActionOnlyAttributeでマークされている任意の方法が唯一アクションまたはRenderAction HTML拡張メソッドで 呼び出すことができます。

属性の使用の詳細については、を参照してください。

+0

ChildActionOnlyは私の問題の適切な修正ですか?それは私がすべてのビューをPartialViewsに変更する必要があるようにそれを使用するように見えます。かなりのURLの問題を解決するために劇的に見えます。しかし、私は知らない。それが私が求めている理由だ。 –

+0

アクションフィルタを作成して、そのアクションにアクセスするための権限をユーザーが持つことを確認できます。 1つのアクションごと、クラスごと、またはグローバルフィルタとして登録することができます – Nkosi

+0

ありがとうございます。私はこれを調べます。私はMVCが初めてです。 [ChildActionOnly]を使用しようとしているのと同じように、私自身のフィルタを作成して使用できるように思えます。私はそれをどうやって行うのか、どのレコードを混乱させようとしているのかを判断しなければならないと思う。 (Idが設定される前にフィルタが適用されていないので、 –

0

Nkosiが正しい答えです。このアイテムへのアクセスを制限するには、Editアクションの中でユーザー確認を実行する必要があります。例:

public ActionResult Edit(string id) 
{ 
    var user = UserManager.FindById(User.Identity.GetUserId()); 
    //Check if user can access item 
} 
+0

私はこれを考えていましたが、既にMVCにオートマジックがあったと思いました。私が考えている方法を変えなければならないのです.Webフォームでは、何かしたくないと思ったら、私はあなたにそれを行う方法を提供しませんでした(例えばクリックすることはできませんでした)。 ( –

+2

@da_jokker:これは決して安全ではありませんでした。このインスタンスのMVCとWebフォームの唯一の違いは、WebフォームがボタンクリックでJavaScript経由でポストを発行したのに対し、MVCだけです要求へのリンクを提供する意志でのest。しかし、Webフォームのやり方は、簡単に逆方向に設計することができます。単にボタンを隠すか、セキュリティではないものを隠すだけです。 –

+0

@da_jokkerバックドアのリンクを確認する必要はありません。自分の行動にコンテンツベースのセキュリティを実装するだけです。アクション自体の中かアクションフィルタの中で行うのはあなたの選択です。 Chrisが言ったように:リンクを隠すだけでは安全ではありません。 –

2

ユーザーが任意のURLにアクセスしようとするのを防ぐ方法はありません。クライアント(ブラウザ)は単にリクエストを出します。何かを返すべきかどうかを判断するのはサーバーの責任です。

アクセスを阻止するためのURLを隠すことは、「暗黙のセキュリティ」と呼ばれ、基本的にセキュリティを全く持たないことと同じです。永続的なユーザーがそれを把握できないということはあまりあいまいではありません。アカウント認証に関連付けられたロールまたはオブジェクトレベルのアクセス許可のように、実際のセキュリティが必要です。

レコードとしては、オブジェクトレベルのアクセス許可が必要です。最も基本的な実装では、そのオブジェクトの「所有権」を表す外部キーをユーザーに作成します。次に、オブジェクトを取得するときに、現在ログインしているユーザーが「所有者」かどうかを確認し、そうでない場合はアクセスを拒否します。より柔軟なアプローチについては

public ActionResult Edit(int id) 
{ 
    var foo = db.Foos.Where(m => m.Id == id && m.OwnerId == User.Identity.GetUserId()); 
    if (foo == null) 
    { 
     return new HttpNotFoundResult(); 
    } 

    // do whatever for authorized user 
} 
+0

ありがとうございました..私はそのカスタムactionresultフィルタを作成することで混乱しましたが、動作しますが、フィルタが所有権を検証するためにデータベースにヒットする必要があったため、完全にファンではなく、そのオブジェクトを渡す必要がありますActionResultに戻るか、ActionResultはビューに渡すために同じレコードを再度プルする必要があります。だから私はレコードを引っ張ってくれることをあなたの多くが示唆しているようなアイデアに行くだろうが、私は "編集"ビューを返す前に、私はユーザーが所有者であることを確認し、そうでない場合は、 –

0

あなたのコントローラのアクションメソッドのカスタムAuthorizeAttributeを作成し、このようにそれを設定することができます:あなたができる「AuthorizeAttribute`の拡張版とその後

[MyAuthorize]  
public ActionResult Edit(string id) 
{ 
    var user = UserManager.FindById(User.Identity.GetUserId()); 
    //Check if user can access item 
} 

をあなたのチェック:

public class MyAuthorizeAttribute : AuthorizeAttribute 
{ 
    // could be used to set the AD group that you are checking for 
    // i.e. [MyAuthorize(strSecurityGroup="domain\group")] in the controller 
    public string strSecurityGroup { get; set; } 
    protected override bool AuthorizeCore(HttpContextBase httpContext) 
    { 
     var authorized = base.AuthorizeCore(httpContext); 
     if (!authorized) 
     { 
      return false; 
     } 
     var rd = httpContext.Request.RequestContext.RouteData; 
     var id = rd.Values["id"]; 
     var userName = httpContext.User.Identity.Name; 
     //Access the current record through a DataHandler class 
     DataHandler dh = new DataHandler(); 
     // Gets a field from the database that holds the username for the owner of the record 
     string createdBy = dh.GetCreatedBy(int.Parse(id.ToString())); 
     bool isAuthorized = false; 
     if (userName.ToString() == createdBy) isAuthorized = true; 
     var User = System.Web.HttpContext.Current.User; 
     if (User.IsInRole(@"domain\group")) isAuthorized = true; 
     return isAuthorized; 
    } 
} 

これは私がADへの承認をしたいのです。 AuthroizeAttributeでクラスプロパティを作成して、属性の使用ごとに個別にユーザーグループを設定することもできます。認可メカニズムを使用してサイト全体のアクションを制御している場合は、毎回認可チェックを手動で実行するよりもきれいです。

関連する問題