2017-07-25 5 views
2

質問Why do we use ViewModels?this answerを見ながら、私はこのセクションに出くわした:ViewModelsは悪意のあるデータベースの変更をどのように防止しますか?

「ビューは、任意の非プレゼンテーションロジックを含めるべきではない」と「あなた ビューを信用してはいけません」(閲覧は可能性があるため、ユーザーが提供する)。 Modelオブジェクトを提供する (アクティブな DatabaseContextに潜在的に接続されている可能性があります)によって、ビューはデータベースに悪意のある変更を加える可能性があります。

これは正確に何を指していますか?私のモデルと私のViewModelにUserIdPasswordがある場合、セキュリティはどこにありますか?コントローラーの何らかのチェック?私たちは何を確認するのですか?

ビューからデータを信頼できると判断するにはどうすればよいですか?これは偽造防止象徴によって取り扱われますか?

+0

ビューモデルを使用すると、アクティブなデータベースにまだ接続されているモデルを使用すると、DBにプッシュする前にデータを検証することができます。ビューは、場合によっては、真のビューモデルで可能です。 –

+0

@Derek ViewModelを使用していない場合よりも不適切に接続を管理することに問題はありませんか? – Sinjai

+0

問題は、モデルバインダーがモデル内の値を盲目的に更新することです。モデルがエンティティフレームワーク内のエンティティのようなものに接続されている場合、必要のないフィールドを更新する可能性があります。適切なビューモデルは、そのようなものから完全に切り離されます。 –

答えて

3

私は答えがオーバーポストの問題を指していると思います。ビューで直接エンティティクラスを利用し、特にそのエンティティをデータベースに直接保存すると、悪意のあるユーザーがフォームを修正して、変更できないフィールドを投稿する可能性があります。

たとえば、ユーザーがウィジェットを編集できるフォームがあるとします。また、行レベルのアクセス権を持っているとしましょう。そのため、ユーザーは自分に属するウィジェットだけを編集できます。だから、私たち架空の悪意のあるユーザーであるJoeは、123というIDで編集できるウィジェットを編集します。しかし、彼はJaneのウィジェットを使いこなすことを決めたので、Idというフォームにフィールドを追加し、Janeのウィジェットid。 Joeがウィジェットフォームを投稿すると、代わりにJaneのウィジェットが更新されます。

ビューモデルはこの問題を解決するためのものではありませんが、本来、ビューモデルをデータベースに直接保存することはできないため、この問題は基本的に無効になります。エンティティをデータベースに保存する前に、ビュー・モデルの値をエンティティにマップする必要があります。その結果、マッピングされたものとマッピングされないものを明示的に制御するので、上記の例でJoeを変更すると、エンティティにマッピングされていないため、IDが変更されなくなります。

実際には、実際のの問題は、直接ユーザーが投稿したものをそのままデータベースに保存することです。実際には、エンティティクラスをビューに「モデル」としてフィードすることはできますが、ポストされたインスタンスは保存しないでください。代わりに、エンティティの新しいインスタンスを作成するか、データベースのインスタンスを新しいインスタンスから取得し、単純にそのインスタンスの値をそのインスタンスにマップします。再度、Idのようなプロパティをマップしないので、再びJoeが挫折します。言い換えれば、問題を解決するのはビューモデルではなく、問題を解決するPOSTを介して作成されたものを直接保存するのに十分なユーザーを信頼することは決してありません。

マイクロソフトではBind属性の形式で別のソリューションを提供しています。これにより、モデルバインディングプロセスのエンティティクラスに特定のプロパティを含める/除外することができます。たとえば、アクションのパラメータを[Bind(Exclude = "Id")]に飾ることで、上記の問題を解決できる可能性があります。Idの投稿された値は破棄されます。しかしはnumber of reasonsで恐ろしく、実際には使用しないでください。代わりに常にビューモデルを使用するか、モデルバインダによって作成されたエンティティインスタンスを直接保存しないでください。

+0

非常に有用な記事正確に関連していませんが、確かに独自の質問を保証するものではありません。コントローラに投稿される内容をどのように変更しますか?私の生成された編集(更新)メソッドは 'int?'を取ります。ビュー内の 'Html.HiddenFor(model => model.Id)'以外のどこから来ているのかは分かりません。抽象度が高すぎるようなものがあります... – Sinjai

+0

ルート(URL)から来るはずです。編集ルートは通常 '/ foo/edit/{id}'のようになります。 '{id}'は編集したい "foo"の主キーです。あなたは隠されたとしてそれを投稿することができますが、再び潜在的なセキュリティ上の問題にあなた自身を開放しています。 URLは特定のリソース(したがって名前)を一意に識別します。したがって、あなたがまったく別のリソースを要求しているという意味で、そこにあるidを変更してください。次に、試行された任意のURL操作を、標準の行レベルの権限で処理できます。 –

+0

'HiddenFor'が生成されました。率直に言って、私はアーキテクチャ全体の理解が壊れやすいので、それを削除することを恐れています。私はまだこの最初のパラメータが 'Update(FooViewModel model、int id)'のどこから来たのか把握しようとしています。ビューは常にモデルをビューに渡しますか、それとも何ですか?あなたはGuardiansで途方もなく素晴らしかったです... – Sinjai

関連する問題