63

管理エリアがあり、管理者だけがそのエリアに入るようにしたいです。Admin 領域のすべてのコントローラーに Authorized 属性を追加することを検討しました。エレガントなソリューションはありませんか、それともこの機能はフレームワーク自体にありませんか?

編集:申し訳ありませんが、これについては前に言及する必要がありました。AuthorizeAttribute から派生したカスタム AuthorizedAttribute を使用しています。

4

7 に答える 7

55

Web.config ベースのセキュリティは、MVC アプリケーションではほとんど使用しないでください。この理由は、複数の URL がコントローラーにヒットする可能性があり、これらのチェックを Web.config に入れると必ず何かが見落とされるためです。注意 - コントローラはエリアに関連付けられていませんが、ルートはエリアに関連付けられています。MVC コントローラー ファクトリは、競合がなければ、領域以外の要求に対して Areas/ フォルダーからコントローラーを喜んで提供します。

たとえば、デフォルトのプロジェクト構造を使用して、AdminDefaultController で管理領域を追加すると、/Admin/AdminDefault/Indexおよび/AdminDefault/Index を介してこのコントローラーをヒットできます。

サポートされている唯一の解決策は、コントローラーの基本クラスに属性を配置し、領域内の各コントローラーがその基本クラスのサブクラスになるようにすることです。

于 2010-02-23T17:47:27.370 に答える
49

私はちょうどこの同じ問題を調査しています。エリアに基づいてコントローラーを保護することはできないため、より単純なオプションが思い浮かびます。

Controller をオーバーライドする各領域のベース コントローラー定義を作成し、これに必要なセキュリティを追加します。次に、領域内の各コントローラーが Controller ではなく AreaController をオーバーライドするようにする必要があります。例えば:

/// <summary>
/// Base controller for all Admin area
/// </summary>
[Authorize(Roles = "Admin")]
public abstract class AdminController : Controller { }

このベースから管理領域の各コントローラーを派生させる必要があります。

public class HomeController : AdminController
{
    // .. actions
}

ただし、少なくとも、エリアのセキュリティを定義する単一のポイントがあります。

于 2013-01-25T08:34:01.453 に答える
18

私はこれを始めたばかりです...しかし、これまでのところ、これは私にとってかなりうまくいっています。

カスタム AuthorizeAttribute クラスを作成し、これを RegisterGlobalFilters 関数に追加します。

CustomAuthorizeAttribute では、領域に基づいてさまざまな条件をチェックします。

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomAuthorizeAttribute());
        filters.Add(new HandleErrorAttribute());
    }
}

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var routeData = httpContext.Request.RequestContext.RouteData;
        var controller = routeData.GetRequiredString("controller");
        var action = routeData.GetRequiredString("action");
        var area = routeData.DataTokens["area"];
        var user = httpContext.User;
        if (area != null && area.ToString() == "Customer")
        {
            if (!user.Identity.IsAuthenticated)
                return false;
        }
        else if (area != null && area.ToString() == "Admin")
        {
            if (!user.Identity.IsAuthenticated)
                return false;
            if (!user.IsInRole("Admin"))
                return false;
        }
        return true;
    }
}
于 2015-09-11T01:16:40.230 に答える
12

すべての管理コードが 1 つのコントローラーにある場合は、Authorize をクラス全体に追加します。

[Authorize]
public class AdminController : Controller
{
     .......
}
于 2010-02-23T15:12:06.767 に答える
-5

.. 非常に大雑把ですが、このようなものが欲しいと思いますか?

迅速で汚い役割管理

[Authorize(Roles = "Admins")]
public ActionResult Register()
{
  ViewData["roleName"] = new SelectList(Roles.GetAllRoles(), "roleName");
  ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
  return View();
}
于 2010-02-23T15:10:47.293 に答える