Tuesday, April 9, 2013

Restituire un errore HTTP 403 Forbidden con ASP.NET MVC

Alle volte può essere utile, in caso di errore, restituire all'utente un messaggio personalizzato insieme al codice HTTP 403 (Forbidden).
Questo indica solitamente che l'accesso alla risorsa richiesta è vietato per qualche ragione e il server non può procedere altrimenti. Diversamente dallo stato 401 Unauthorized, che indica un accesso non autorizzato, le credenziali non servono e non permetterebbero comunque di visualizzare la pagina.

Per gestire questa situazione in ASP.NET MVC possiamo creare un helper personalizzato che deve soddisfare le seguenti condizioni:
  • Deve essere facile e immediato da utilizzare
  • Deve restituire al browser il codice di errore 403 insieme allo stato Forbidden
  • Non deve effettuare un redirect ma la pagina deve rimanere la stessa
  • Deve mostrare all'utente una view personalizzata
Ho creato la classe HttpForbiddenResult ereditando dalla classe HttpStatusCodeResult già esistente in ASP.NET MVC. In questo modo il framework si occuperà automaticamente di impostare il codice di errore e la descrizione. Il codice completo della classe è il seguente:

public class HttpForbiddenResult : HttpStatusCodeResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        base.ExecuteResult(context);

        // crea il ViewResult impostando anche i parametri ViewData e TempData
        ViewResult result = new ViewResult
        {
            ViewName = "AccessDenied",
            ViewData = context.Controller.ViewData,
            TempData = context.Controller.TempData
        };

        result.ExecuteResult(context);
    }

    // richiama il costruttore base con il codice 403
    public HttpForbiddenResult()
        : base(HttpStatusCode.Forbidden, "Forbidden")
    {
    }
}

Ho creato quindi una view chiamata AccessDenied all'interno della cartella Shared, contenente un messaggio per gli utenti che visualizzeranno la pagina di errore:

@{
    ViewBag.Title = "Access Denied";
}

<h2>Access Denied</h2>

<p>Sorry, the access to this page is denied.</p>

Per utilizzare l'helper appena creato saranno sufficienti le seguenti linee di codice:

public class HomeController : Controller
{
    public ActionResult DoSomething(string taskName)
    {
        // accesso negato quando il parametro taskName è vuoto
        if (string.IsNullOrEmpty(taskName))
        return new HttpForbiddenResult();

        return View();
    }
}

Andando quindi con il browser alla URL del controller precedente senza il parametro taskName il risultato sarà questo:


Chiaramente con le opportune modifiche è possibile realizzare un helper per tutti i codici di errore HTTP che ci interessano!

No comments:

Post a Comment