Comment puis-je créer un AuthorizeAttribute personnalisé qui est spécifique à la région, le contrôleur et l'action?

En d'autres termes, est-ce vraiment une idée stupide?

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeActionAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        //get the area, controller and action
        var area = filterContext.RouteData.Values["area"];
        var controller = filterContext.RouteData.Values["controller"];
        var action = filterContext.RouteData.Values["action"];
        string verb = filterContext.HttpContext.Request.HttpMethod;

        //these values combined are our roleName
        string roleName = String.Format("{0}/{1}/{2}/{3}", area, controller, action, verb);

        //set role name to area/controller/action name
        this.Roles = roleName;

        base.OnAuthorization(filterContext);
    }
}

Mise à JOUR
J'essaie d'éviter le suivant, dans un scénario où nous avons très précise des rôles des autorisations parce que les rôles sont le programme d'installation sur une base par client et attaché à des groupes d'utilisateurs:

public partial class HomeController : Controller
{
    [Authorize(Roles = "/supplierarea/homecontroller/indexaction/")]
    public virtual ActionResult Index()
    {
        return View();
    }

    [Authorize(Roles = "/supplierarea/homecontroller/aboutaction/")]
    public virtual ActionResult About()
    {
        return View();
    }
}

Quelqu'un peut-il m'éclairer de manière sécurisée à écrire ce AuthorizeRouteAttribute pour accéder à la route de l'information et de l'utiliser comme le nom de rôle? Comme Lévi dit, la RouteData.Les valeurs n'est pas sécurisé.

Est l'utilisation de l'organe d'exécution httpContext.Demande.Chemin plus sécurisée ou de meilleures pratiques?

public override void OnAuthorization(AuthorizationContext filterContext)
{
    if (filterContext == null)
    {
        throw new ArgumentNullException("filterContext");
    }

    if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
    {
        //auth failed, redirect to login page
        filterContext.Result = new HttpUnauthorizedResult();
        return;
    }

    var path = filterContext.HttpContext.Request.Path;
    var verb = filterContext.HttpContext.Request.HttpMethod;

    //these values combined are our roleName
    string roleName = String.Format("{0}/{1}", path, verb);

    if (!filterContext.HttpContext.User.IsInRole(roleName))
    {
        //role auth failed, redirect to login page
        filterContext.Result = new HttpUnauthorizedResult();
        //P.S. I want to tell the logged in user they don't 
        //have access, not ask them to login. They are already
        //logged in!
        return;
    }

    //
    base.OnAuthorization(filterContext);
}

Cette illustre peut-être la question un peu plus loin:

enum Version
{
PathBasedRole,
InsecureButWorks,
SecureButMissingAreaName
}
string GetRoleName(AuthorizationContext filterContext, Version version)
{
//
var path = filterContext.HttpContext.Request.Path;
var verb = filterContext.HttpContext.Request.HttpMethod;
//recommended way to access controller and action names
var controller = 
filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
var action = 
filterContext.ActionDescriptor.ActionName;
var area = "oh dear...."; //mmmm, where's thearea name???
//
var insecureArea = filterContext.RouteData.Values["area"];
var insecureController = filterContext.RouteData.Values["controller"];
var insecureAction = filterContext.RouteData.Values["action"];
string pathRoleName = 
String.Format("{0}/{1}", path, verb);
string insecureRoleName = 
String.Format("{0}/{1}/{2}/{3}", 
insecureArea, 
insecureController, 
insecureAction, 
verb);
string secureRoleName = 
String.Format("{0}/{1}/{2}/{3}", 
area, 
controller, 
action, 
verb);
string roleName = String.Empty;
switch (version)
{
case Version.InsecureButWorks:
roleName = insecureRoleName;
break;
case Version.PathBasedRole:
roleName = pathRoleName; 
break;
case Version.SecureButMissingAreaName:
//let's hope they don't choose this, because
//I have no idea what the area name is
roleName = secureRoleName;
break;
default:
roleName = String.Empty;
break;
}
return roleName;
}

OriginalL'auteur Rebecca | 2011-02-03