Sur de nombreux projets web, j’ai pu voir des personnes être bloquées pour rediriger les utilisateurs vers une page de login personnalisée. Elles avaient monté des authentifications Custom sans Forms. Pourtant, elles utilisaient la configuration de l’authentification Forms pour fixer la page de Login.

Exemple :

<system.web>
  <authentication mode="Forms">
    <forms loginurl="~/Login">
  </forms>
  </authentication>
</system.web>

Ceci n’est pas très élégant et peut compliquer la compréhension de vos intentions : « Authentification Forms, ou pas Forms ???? »

Heureusement, il existe une solution plus élégante : Coder un module de redirection. Ce module aura pour vocation de rediriger l’utilisateur dès que l’accès à une page lui est refusé. Ceci, sans avoir connaissance des processus d’authentification et d’autorisation.

Pour l’exemple, j’ai codé le module suivant :

- Dès qu’une erreur 401 est produite, on redirige l’utilisateur, vers la page de login.

- La page peut être configurée via les AppSettings.

Ce qui donne ceci :

using System;
using System.Configuration;
using System.IdentityModel.Services;
using System.Web;

namespace MyDemo.Modules
{
    public sealed class LoginPageHttpModule : HttpModuleBase
    {
        private const string LoginPageSettingsKey = "LoginPage";
        private const String LoginPageDefault = "~/Login";        
        private String _loginPage;

        /// 
        /// Chargement de la configuration
        /// 
        protected override void InitializePropertiesFromConfiguration()
        {
            // Utilisation des settings, si il sont présents
            _loginPage = ConfigurationManager.AppSettings[LoginPageSettingsKey] ?? LoginPageDefault;
        }

        /// 
        /// Initialisation du module
        /// 
        /// 
        protected override void InitializeModule(HttpApplication context)
        {
            // S'abonner pour connaitres les réponse données aux utilisateurs
            context.EndRequest += Context_EndRequest;
        }

        /// 
        /// Action en fin de request web
        /// 
        /// 
        /// 
        private void Context_EndRequest(object sender, EventArgs e)
        {
            // Test si il y a un refus d'autorisation
            if (HttpContext.Current.Response.StatusCode == 401)
            {
                HttpContext.Current.Response.Redirect(_loginPage);
            }
        }
    }
}

Côté configuration, il suffit d’ajouter le module à la liste des modules web

<system.webserver>
  <modules>
    <add name="LoginPageHttpModule" type="MyDemo.Modules.LoginPageHttpModule, MyDemo"/>
  </modules>
</system.webserver>

Et on peut définir sa page via les settings

<appsettings>
  <add value="~/Login" key="LoginPage"/>
</appsettings>

Voila ! Simple et efficace en WebForm comme en MVC ;)