2011-01-07 12 views
3

私はカスタムメンバーシッププロバイダを使用しています。すべてがうまくいっています。しかし、私のweb.configファイルでは、サイト全体がロックされるように「ユーザーを拒否する」が有効になっています。ASP.NET MVC 2認証の問題

これは素晴らしいです。ユーザーはログインページにリダイレクトされます。

ここで、匿名アクセスを許可するコントローラ/アクションがいくつかあります。私が匿名を望むコントローラ/アクションのためにそれらをすべてのコントローラに置き、[許可]属性を置くことです。

これは私には逆のようです。私はすべてをデフォルトでロックし、匿名のものをロック解除する方が好きです。

方法はありますか?

ありがとうございます!

答えて

3

これを実装する別の方法が考えられますが、すべてカスタマイズされたAuthorizeAttributeを使用する必要があります。これを行う1つの方法は、カスタマイズされたAuthorizeAttributeを使用してすべてのコントローラが派生する基本コントローラを持つことです。この属性は、コントローラーでないかアクション自体が別の属性(例えば、AnonymousEnabledAttribute)で装飾されていない限り、アクションへの匿名(および権限のない)アクセスを防ぐためにカスタマイズされます。すべてのコントローラはこのコントローラから派生し、そのため、標準の「デフォルトでは匿名ではない」動作を継承します。 AnonymousEnabledAttributeを使用して、匿名にしたいコントローラ/アクションを単純に装飾して、そのコントローラまたはアクションのオーバーライドを提供します。または、コントローラの場合は、保護されたコントローラから継承しないでください。すべてのアクションは公開されます。

ああ、あなたのサイト全体を開いたままにしておく必要があります。

[OverridableAuthorize] 
public abstract class ProtectedController : Controller 
{ 
} 

public class MostlyProtectedController : ProtectedController 
{ 
    public ActionResult ProtectedAction() 
    { 
    } 

    [AnonymousEnabled] 
    public ActionResult PublicAction() 
    { 
    } 
} 

[AnonymousEnabled] 
public class ExplicitlyPublicController : ProtectedController 
{ 
    // inherits additional behaviors, but anonymous is enabled by attribute 
} 

public class PublicByOmissionController : Controller 
{ 
    // doesn't inherit and is thus public -- assuming whole site is open 
} 

public class AnonymousEnabledAttribute : Attribute 
{ 
} 

public class OverridableAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext context) 
    { 
      context.HttpContext.Items["ActionDescriptor"] = context.ActionDescriptor; 
      base.OnAuthorize(context); 
    } 

    public override bool AuthorizeCore(HttpContextBase context) 
    { 
     var actionDescriptor = context.Items["ActionDescriptor"] as ActionDescriptor; 
     if (actionDescriptor == null) 
     { 
      throw InvalidOperationException("ActionDescriptor missing from context"); 
     } 
     var attribute = actionDescriptor 
          .GetCustomAttributes(typeof(AnonymousEnabledAttribute,true) 
          .FirstOrDefault(); 
     if (attribute == null) 
     { 
      return base.AuthorizeCore(context); 
     } 
     return true; 
    } 
} 
+0

感謝を。つまり、これはweb.configのようなサイトが完全に開いていることを意味しますが、ProtectedControllerから継承している限り、すべてのコントローラはデフォルトでロックダウンされますか? – cbmeeks

+0

@cbmeeks - 正しい。また、AuthorizeAttribute(またはそれから派生したもの)、つまりMVCセキュリティを使用することは、WebFormsベースのセキュリティとMVCセキュリティを組み合わせようとするよりもはるかに望ましいことだと思います。 – tvanfosson

+0

**注意** AuthorizeAttributeクラスは、作成後は変更できないようにする必要があります。 HttpContext.Itemsを使用してActionDescriptorを格納することはできますが、クラス内のインスタンスフィールドとして絶対に*保存してはいけません*。この理由は、複数の同時リクエストを処理するためにAuthorizeAttributeの1つのインスタンスを使用でき、インスタンスコードを導入することによって、セキュリティコードに競合状態が発生するためです。 – Levi

1

あなたは常に許可するコントローラ用のweb.configファイル内の場所を作成することができます。この提案のための

<configuration> 
    <system.web> 
     ... 
     <authorization> 
      <deny users="?" /> 
     </authorization> 
    </system.web> 
    ... 
    <location path="MyArea/MyController"> 
     <system.web> 
      <authorization> 
       <allow users="*" /> 
      </authorization> 
     </system.web> 
    </location> 
    ... 
</configuration> 
+0

ありがとうございますが、これはうまくいかないようです。私はこれを入れましたが、それでもまだ匿名のアクションの許可が必要です。 – cbmeeks

+0

@cbmeeks:私は何を言うべきか分からない。私たちはこのアプローチを使用しています。 – StriplingWarrior

+1

**注意** ベースのセキュリティとMVCセキュリティを混在させようとするのは、災害のためのレシピです。 ベースのセキュリティは、.aspxページなどのファイルベースのリソースを対象としています。コントローラクラスはファイルベースではなくタイプベースであるため、ベースのセキュリティをバイパスできます。 – Levi