2008-11-30 6 views

Répondre

13

Je ne pense pas que vous pouvez le faire avec l'attribut standard AUTORISER, mais vous pouvez obtenir votre propre attribut de AuthorizeAttribute qui prend une liste d'actions pour permettre et permet l'accès aux seules actions. Vous pouvez consulter la source de AuthorizeAttribute au www.codeplex.com pour obtenir des idées sur la façon de procéder. Si vous avez fait, il pourrait ressembler à:

[AdminAuthorize (Roles = "Administrator", Exempt = "Login, Logout") ] 
public class AdminController : Controller 
{ 
    public ActionResult Login() 
    { 
     return View(); 
    } 

    public ActionResult Login() 
    { 
     return View(); 
    } 

    ... other, restricted actions ... 
} 

EDIT: Pour votre information, j'ai finalement couru à travers un besoin de faire quelque chose de semblable à moi-même et je suis une autre direction. J'ai créé un fournisseur de filtre d'autorisation par défaut et j'applique un filtre d'autorisation global. Le fournisseur de filtre d'autorisation utilise la réflexion pour vérifier si une action ou un contrôleur a un attribut d'autorisation spécifique appliqué et, dans l'affirmative, s'en remet à lui. Sinon, il applique un filtre d'autorisation par défaut. Ceci est couplé avec un PublicAttribute dérivé de AuthorizeAttribute qui permet un accès public. Maintenant, je reçois un accès sécurisé par défaut, mais peut accorder un accès public via [Public] appliqué à une action ou un contrôleur. Une autorisation plus spécifique peut également être appliquée si nécessaire. Voir mon blog à http://farm-fresh-code.blogspot.com/2011/04/default-authorization-filter-provider.html

+0

On dirait que vous avez raison selon http://www.codeplex.com/aspnet/SourceControl/changeset/view/17272 Je suppose que l'attribut est appliqué au niveau du contrôleur et ne donne jamais une tentative d'évaluation à l'action. –

+0

Hmm, apparemment, vous ne pouvez pas lier directement au fichier source sur codeplex. –

4

Vous pouvez remplacer la méthode OnAuthorization du contrôleur

protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if ((string)(filterContext.RouteData.Values["action"]) == "Login") 
     { 
      filterContext.Cancel = true; 
      filterContext.Result = Login(); 
     } 
    } 

Cela fonctionne, mais il est un hack.

code de classe complète utilisée pour les tests:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using System.Web.Mvc.Ajax; 

namespace MvcApplication2.Controllers 
{ 
[HandleError] 
[Authorize] 
public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     ViewData["Title"] = "Home Page"; 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 

     return View(); 
    } 


    public ActionResult About() 
    { 
     ViewData["Title"] = "About Page"; 

     return View(); 
    } 


    protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if ((string)(filterContext.RouteData.Values["action"]) == "Index") 
     { 
      filterContext.Cancel = true; 
      filterContext.Result = Index(); 
     } 
    } 
} 
} 
+0

Est-ce que cela est appelé avant ou après l'attribut [Autoriser]? –

+0

Il semble que l'attribut [Authoirze] soit évalué en premier et n'atteigne jamais la méthode OnAuthoirization. –

+0

Est appelé chaque fois pour moi. – MrJavaGuy

1

Peut être ce n'est pas réelle, mais j'écrit mon attribut personnalisé:

public class SelectableAuthorizeAttribute : AuthorizeAttribute 
{ 
    public SelectableAuthorizeAttribute(params Type[] typesToExclude) 
    { 
     _typesToExlude = typesToExclude; 
    } 

    private readonly Type[] _typesToExlude; 

    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     bool skipAuthorization = _typesToExlude.Any(type => filterContext.ActionDescriptor.ControllerDescriptor.ControllerType == type); 

     if (!skipAuthorization) 
     { 
      base.OnAuthorization(filterContext); 
     } 
    } 
} 

Et puis enregistré dans mes filetrs mondiales:

filters.Add(new SelectableAuthorizeAttribute(typeof(MyController))); 

Espérons que cela sera utile pour quelqu'un

23

Vous pouvez décorer votre contrôleur avec [Authorize], puis vous pouvez simplement décorer la méthode que vous souhaitez exempter avec [AllowAnonymous]

+3

N'est-ce pas la bonne réponse? Ou peut-être ce n'était pas le cas en 2008 lorsque la question a été posée ... –

+1

Cela a fonctionné pour MVC5, merci !. –

Questions connexes