それで、独自の認証ルーチンを実装するのがいかに悪いかについて読みました!
そして、私は自分の行動をそのように実装していたので怖くなりました(たとえば、認証されたユーザーがログインしているユーザーではない場合、アカウントの詳細へのアクセスを防止します)
public ActionResult DisplayAccount(int someid){
Account a = context.Accounts.Single(a => a.id == someid);
// currentUserId() returns userid from FormsAuthentication
if (!a.owner == currentUserId()){
/* Not Authorised! */
}
}
これは明らかに、ASP がアクションをキャッシュすることを決定した場合に壊れることを意味します (そのため、アクションは実行されません)。
だから私は今、AuthorizeAttributeを使って私がしなければならないことをすることを検討しています。
- 認証されていない場合、アクションへのアクセスを防止する
- 認証されたユーザーが取得したリソースにアクセスできるかどうかを確認します
しかし、私はそれについて考えるたびに、2番目のポイントを実装する方法について考えることができません. 役割はサイト全体のレベルであるため機能しませんが、アプリケーション内ではユーザーにも役割 (所有者、モデレーター、寄稿者、ユーザーなど) があり、アプリケーションのそれぞれの部分内でのみこれらの役割を持ちます (例: スレッドの所有者、wiki への寄稿者、フォーラムのモデレーターなど)
AuthorizeCore をオーバーライドするいくつかの例に出くわしました。持っているリソースごとに複数の AuthorizeAttribute サブクラスを作成することを想像できます (幸いなことに、それほど多くはありません)。しかし、それを見るだけで、そのアクションを実行するたびにデータベースにクエリを実行して、ログインしているユーザーがそのデータにアクセスして、クエリでそれを行う代わりに、アクションでデータベースにクエリを実行してモデルを取得できますか?
だから私の質問は
- キャッシングが多すぎることを心配しすぎていますか?次のいずれかが発生しますか
- Web サイトは、ユーザー B の画面に表示されるユーザー A の詳細をキャッシュしますか?
- Web サイトはページの管理者バージョン (編集コントロール付き) をキャッシュし、通常のユーザーにはキャッシュされたバージョンが表示されますか?
- AuthorizeAttribute の使用は当然のことですが、アクションの前にデータベースにアクセスすることなく、ポイント 2 で必要なことをどのように達成できますか? または、いずれにしてもそれを達成するための最良の方法は何ですか。
- それとも、ユーザーがログインしているかどうかを判断するためにのみ AuthorizeAttribute を使用し、アクションで他のチェックロジックを実行しますか?
とにかく、この投稿が古い道を踏んでいないことを願っています(決定的なものは何も見つかりませんでした)
編集:キャッシングを有効にしなければ、この問題は発生しないと思いますが、これは正しいですか?
編集: 今のところ、バニラの AuthorizeAttribute を使用してから、アクションでリソース レベルのアクセスを確認し、認証されたアクションにキャッシュを使用しないようにします。うまくいけば、今週中にこれに対するより多くの答えが得られるでしょう.