32 votes

Attribut Asp.net MVC Authorize, rediriger vers la page personnalisée "sans droits"

Asp.net MVC2 ne rediriger vers la page de login avec response 302 lorsque l'utilisateur authentifié n'a pas de droits.

Je voudrais diviser en deux actions

  1. Si l'utilisateur n'est pas authentifié puis faire ce qu'il fait, rediriger vers la page de connexion.
  2. Si l'utilisateur est authentifié, mais n'a pas les droits requis puis retour approprié code d'état http et ne montrent pas de droits de mec de la page.

Est-il possible de le faire? Ou suis-je en train de faire quelque chose de mal avec l'autorisation et authentification par formulaire? Seule façon que je peux penser, c'est par l'écriture personnalisée autoriser attribut, que je veux éviter.

19voto

hellangle Points 327

Vous pouvez écrire un attribut de filtre personnalisé comme ceci:

 public class CustomAuthorizeAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.User.Identity == null || !filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                filterContext.Result = new RedirectResult(System.Web.Security.FormsAuthentication.LoginUrl + "?returnUrl=" +
                filterContext.HttpContext.Server.UrlEncode(filterContext.HttpContext.Request.RawUrl));
            }

            //Check user right here
            if (userNotRight)
            {
                filterContext.HttpContext.Response.StatusCode = 302;
                filterContext.Result = new HttpUnauthorizedResult();
            }
        }
    }
 

Et utilisez-le dans le contrôleur:

 [CustomAuthorize]
public class HomeController : Controller
{

}
 

9voto

Darin Dimitrov Points 528142

Vous pourriez écrire un personnalisé autoriser attribut et dans le AuthorizeCore méthode si l'utilisateur n'est pas authentifié retour d'un HttpUnauthorizedResult et s'il est authentifié, mais pas dans les rôles d'effectuer une autre action que vous souhaitez. Notez que si vous retournez 401 code de statut de la FormsAuthentication cadre finira par redirection 302 vers la page de connexion.

7voto

Brian Rogers Points 113

Comme suggéré dans Personnalisation de l'autorisation dans ASP.NET MVC , vous pouvez sous-classer AuthorizeAttribute pour intercepter le scénario authentifié mais non autorisé et remplacer le résultat par une redirection.

7voto

Andreas Points 384

Implémentez un AuthorizeAttribute et ajoutez le remplacement suivant. L'essentiel est de vérifier si l'utilisateur est authentifié mais non autorisé, puis de rediriger vers votre propre page "Accès refusé". J'espère que cela t'aides!

 public override void OnAuthorization(AuthorizationContext filterContext) 
{
    base.OnAuthorization(filterContext);

    // Check if user is authenticated and if this action requires authorization
    if (filterContext.HttpContext.User.Identity.IsAuthenticated
        && filterContext.ActionDescriptor.IsDefined(typeof(AuthorizeAttribute), true)
        || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AuthorizeAttribute), true))
    {
        List<object> attributes = new List<object>(filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));
        attributes.AddRange(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true));

        // Check all authorzation attributes
        foreach (var attribute in attributes)
        {
            var authAttribute = attribute as AuthorizeAttribute;
            if (authAttribute != null)
            {
                if (!filterContext.HttpContext.User.IsInRole(authAttribute.Roles))
                {
                    // User is not authorized so redirect to our access denied error page
                    filterContext.Result = new RedirectToRouteResult(
                        new RouteValueDictionary 
                            {
                                { "area", "" },
                                { "controller", "Error" },
                                { "action", "AccessDenied" }
                            });
                    break;
                }
            }
        }
    }
}
 

3voto

wiser Points 39

Semblables à des solutions suggérées par @hellangle et @Andreas, j'ai utilisé le code suivant pour résoudre ce problème:

public class CustomizedAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var userAuthInfo = GetUserAuthInfo();

        if (!userAuthInfo.IsAuthenticated())
        {
            filterContext.Result = new RedirectResult(UrlToYourLoginPage);
            return;
        }

        if (!userAuthInfo.IsAuthorized())
        {
            var result = new ViewResult {ViewName = "UnAuthorized"};
            result.ViewBag.Message = "Sorry! You are not authorized to do this!";
            filterContext.Result = result;
        }
    }
}

Bien sûr, vous avez besoin pour mettre en œuvre l'autorisation de l'utilisateur de l'information de classe et les méthodes connexes (GetUserAuthInfo, IsAuthenticated, IsAuthorized) en fonction de vos besoins spécifiques. Également d'une Vue nommée "non autorisé" doit être mis quelque part le MVC moteur peut trouver. Ensuite, il peut être utilisé sur un contrôleur de classe (souligné dans @hellangle de réponse) ou une méthode d'action:

[CustomizedAuthorizeAttribute]
public class TargetController : Controller
{
    [CustomizedAuthorizeAttribute]
    public ActionResult TargetAction()
    {
        // Your Code
    }

}

Afin de fournir différentes stratégie de contrôle d'accès pour les différentes classes de contrôleur et des méthodes d'action, met en œuvre un constructeur pour CustomizedAuthorizeAttribute classe qui accepte en paramètre(s) représentant les informations de contrôle d'accès et ensuite Instancier CustomizedAuthorizeAttribute classe en conséquence.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X