3

[Authorize] 属性を使用すると、特定のユーザーまたはロールのみに許可されるアクションを簡単に設定できます。例えば

[Authorize(Roles = "Administrator")]
public ActionResult Index()
{
  ...

しかし、逆が必要なときに問題が発生しました。MVC フレームワーク機能を使用して、名前または役割で指定されたユーザーを除くすべての認証済みユーザーを許可する方法はありますか?

望ましい使用法は次のようなものです。

[DoNotAuthorize(Roles = "RestrictedUser")]
public ActionResult Index()
{
  ...
4

5 に答える 5

6

非常に単純な解決策の 1 つは、AuthorizeAttribute クラスから派生させ、その AuthorizeCore メソッドをオーバーライドして、その true/false ロジックを交換することです。

/// <summary>
/// Authorizes any authenticated user *except* those who match the provided Users or Roles.
/// </summary>
public class DoNotAuthorizeAttribute : AuthorizeAttribute
{
    /// <summary>
    /// This is effectively a copy of the MVC source for AuthorizeCore with true/false logic swapped.
    /// </summary>
    /// <param name="httpContext">The HTTP context, which encapsulates all HTTP-specific information about an individual HTTP request.</param>
    /// <returns>true if the user is authorized; otherwise, false.</returns>
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }
        IPrincipal user = httpContext.User;
        if (!user.Identity.IsAuthenticated)
        {
            return false;
        }

        string[] usersSplit = SplitString(Users);
        if ((usersSplit.Length > 0) && usersSplit.Contains<string>(user.Identity.Name, StringComparer.OrdinalIgnoreCase))
        {
            return false;
        }

        string[] rolesSplit = SplitString(Roles);
        if ((rolesSplit.Length > 0) && rolesSplit.Any<string>(new Func<string, bool>(user.IsInRole)))
        {
            return false;
        }

        return true;
    }

    /// <summary>
    /// This is a direct copy of the MVC source for the internal SplitString method.
    /// </summary>
    /// <param name="original">The original string to split.</param>
    /// <returns>An array of strings.</returns>
    internal static string[] SplitString(string original)
    {
        if (string.IsNullOrWhiteSpace(original))
        {
            return new string[0];
        }
        return (from piece in original.Split(new[] { ',' })
                let trimmed = piece.Trim()
                where !string.IsNullOrEmpty(trimmed)
                select trimmed).ToArray<string>();
    }
}
于 2012-12-14T00:16:39.867 に答える
1

受け入れられた役割をリストし、例外を除外することができます

[Authorize(Roles = "Administrator, Admin, SuperUser")]
public ActionResult Index()
{
}

または、そのロジックで特別な AuthorizeAttribute を作成します

于 2012-12-14T00:21:45.317 に答える