Authentification de base dans API Web ASP.NETBasic Authentication in ASP.NET Web API

par Mike Wassonby Mike Wasson

L’authentification de base est définie dans le document RFC 2617, authentification http : authentification d’accès de base et Digest.Basic authentication is defined in RFC 2617, HTTP Authentication: Basic and Digest Access Authentication.

InconvénientsDisadvantages

  • Les informations d’identification de l’utilisateur sont envoyées dans la demande.User credentials are sent in the request.
  • Les informations d’identification sont envoyées en texte clair.Credentials are sent as plaintext.
  • Les informations d’identification sont envoyées avec chaque demande.Credentials are sent with every request.
  • Aucun moyen de se déconnecter, sauf en mettant fin à la session du navigateur.No way to log out, except by ending the browser session.
  • Vulnérable à la falsification de requête intersites (CSRF); requiert des mesures anti-CSRF.Vulnerable to cross-site request forgery (CSRF); requires anti-CSRF measures.

AvantagesAdvantages

  • Internet standard.Internet standard.
  • Pris en charge par tous les principaux navigateurs.Supported by all major browsers.
  • Protocole relativement simple.Relatively simple protocol.

L’authentification de base fonctionne comme suit :Basic authentication works as follows:

  1. Si une demande requiert une authentification, le serveur retourne 401 (non autorisé).If a request requires authentication, the server returns 401 (Unauthorized). La réponse comprend un en-tête WWW-Authenticate, indiquant que le serveur prend en charge l’authentification de base.The response includes a WWW-Authenticate header, indicating the server supports Basic authentication.
  2. Le client envoie une autre demande, avec les informations d’identification du client dans l’en-tête Authorization.The client sends another request, with the client credentials in the Authorization header. Les informations d’identification sont mises en forme en tant que chaîne « nom : mot de passe », encodée en base64.The credentials are formatted as the string "name:password", base64-encoded. Les informations d’identification ne sont pas chiffrées.The credentials are not encrypted.

L’authentification de base est effectuée dans le contexte d’un « domaine ».Basic authentication is performed within the context of a "realm." Le serveur comprend le nom du domaine dans l’en-tête WWW-Authenticate.The server includes the name of the realm in the WWW-Authenticate header. Les informations d’identification de l’utilisateur sont valides dans ce domaine.The user's credentials are valid within that realm. La portée exacte d’un domaine est définie par le serveur.The exact scope of a realm is defined by the server. Par exemple, vous pouvez définir plusieurs domaines afin de partitionner les ressources.For example, you might define several realms in order to partition resources.

Étant donné que les informations d’identification sont envoyées non chiffrées, l’authentification de base est sécurisée uniquement via HTTPs.Because the credentials are sent unencrypted, Basic authentication is only secure over HTTPS. Consultez utilisation de SSL dans l’API Web.See Working with SSL in Web API.

L’authentification de base est également vulnérable aux attaques CSRF.Basic authentication is also vulnerable to CSRF attacks. Une fois que l’utilisateur a entré les informations d’identification, le navigateur les envoie automatiquement aux demandes suivantes au même domaine, pour la durée de la session.After the user enters credentials, the browser automatically sends them on subsequent requests to the same domain, for the duration of the session. Cela comprend les demandes AJAX.This includes AJAX requests. Consultez la page prévention des attaques de falsification de requête intersites (CSRF).See Preventing Cross-Site Request Forgery (CSRF) Attacks.

Authentification de base avec IISBasic Authentication with IIS

IIS prend en charge l’authentification de base, mais il y a un inconvénient : l’utilisateur est authentifié par rapport à ses informations d’identification Windows.IIS supports Basic authentication, but there is a caveat: The user is authenticated against their Windows credentials. Cela signifie que l’utilisateur doit disposer d’un compte sur le domaine du serveur.That means the user must have an account on the server's domain. Pour un site Web public, vous souhaitez généralement vous authentifier auprès d’un fournisseur d’appartenances ASP.NET.For a public-facing web site, you typically want to authenticate against an ASP.NET membership provider.

Pour activer l’authentification de base à l’aide d’IIS, définissez le mode d’authentification sur « Windows » dans le fichier Web. config de votre projet ASP.NET :To enable Basic authentication using IIS, set the authentication mode to "Windows" in the Web.config of your ASP.NET project:

<system.web>
    <authentication mode="Windows" />
</system.web>

Dans ce mode, IIS utilise les informations d’identification Windows pour s’authentifier.In this mode, IIS uses Windows credentials to authenticate. En outre, vous devez activer l’authentification de base dans IIS.In addition, you must enable Basic authentication in IIS. Dans le gestionnaire des services Internet, accédez à l’affichage des fonctionnalités, sélectionnez authentification, puis activez l’authentification de base.In IIS Manager, go to Features View, select Authentication, and enable Basic authentication.

Dans votre projet d’API Web, ajoutez l’attribut [Authorize] pour toutes les actions de contrôleur qui nécessitent une authentification.In your Web API project, add the [Authorize] attribute for any controller actions that need authentication.

Un client s’authentifie lui-même en définissant l’en-tête d’autorisation dans la demande.A client authenticates itself by setting the Authorization header in the request. Les clients de navigateur effectuent cette étape automatiquement.Browser clients perform this step automatically. Les clients qui ne sont pas des navigateurs doivent définir l’en-tête.Nonbrowser clients will need to set the header.

Authentification de base avec appartenance personnaliséeBasic Authentication with Custom Membership

Comme mentionné précédemment, l’authentification de base intégrée à IIS utilise les informations d’identification Windows.As mentioned, the Basic Authentication built into IIS uses Windows credentials. Cela signifie que vous devez créer des comptes pour vos utilisateurs sur le serveur d’hébergement.That means you need to create accounts for your users on the hosting server. Toutefois, pour une application Internet, les comptes d’utilisateurs sont généralement stockés dans une base de données externe.But for an internet application, user accounts are typically stored in an external database.

Le code suivant montre comment un module HTTP qui effectue l’authentification de base.The following code how an HTTP module that performs Basic Authentication. Vous pouvez facilement intégrer un fournisseur d’appartenances ASP.NET en remplaçant la méthode CheckPassword, qui est une méthode factice dans cet exemple.You can easily plug in an ASP.NET membership provider by replacing the CheckPassword method, which is a dummy method in this example.

Dans l’API Web 2, vous devez envisager d’écrire un filtre d’authentification ou un intergiciel (middleware) OWINà la place d’un module http.In Web API 2, you should consider writing an authentication filter or OWIN middleware, instead of an HTTP module.

namespace WebHostBasicAuth.Modules
{
    public class BasicAuthHttpModule : IHttpModule
    {
        private const string Realm = "My Realm";

        public void Init(HttpApplication context)
        {
            // Register event handlers
            context.AuthenticateRequest += OnApplicationAuthenticateRequest;
            context.EndRequest += OnApplicationEndRequest;
        }

        private static void SetPrincipal(IPrincipal principal)
        {
            Thread.CurrentPrincipal = principal;
            if (HttpContext.Current != null)
            {
                HttpContext.Current.User = principal;
            }
        }

        // TODO: Here is where you would validate the username and password.
        private static bool CheckPassword(string username, string password)
        {
            return username == "user" && password == "password";
        }

        private static void AuthenticateUser(string credentials)
        {
            try
            {
                var encoding = Encoding.GetEncoding("iso-8859-1");
                credentials = encoding.GetString(Convert.FromBase64String(credentials));

                int separator = credentials.IndexOf(':');
                string name = credentials.Substring(0, separator);
                string password = credentials.Substring(separator + 1);

                if (CheckPassword(name, password))
                {
                    var identity = new GenericIdentity(name);
                    SetPrincipal(new GenericPrincipal(identity, null));
                }
                else
                {
                    // Invalid username or password.
                    HttpContext.Current.Response.StatusCode = 401;
                }
            }
            catch (FormatException)
            {
                // Credentials were not formatted correctly.
                HttpContext.Current.Response.StatusCode = 401;
            }
        }

        private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
        {
            var request = HttpContext.Current.Request;
            var authHeader = request.Headers["Authorization"];
            if (authHeader != null)
            {
                var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);

                // RFC 2617 sec 1.2, "scheme" name is case-insensitive
                if (authHeaderVal.Scheme.Equals("basic",
                        StringComparison.OrdinalIgnoreCase) &&
                    authHeaderVal.Parameter != null)
                {
                    AuthenticateUser(authHeaderVal.Parameter);
                }
            }
        }

        // If the request was unauthorized, add the WWW-Authenticate header 
        // to the response.
        private static void OnApplicationEndRequest(object sender, EventArgs e)
        {
            var response = HttpContext.Current.Response;
            if (response.StatusCode == 401)
            {
                response.Headers.Add("WWW-Authenticate",
                    string.Format("Basic realm=\"{0}\"", Realm));
            }
        }

        public void Dispose() 
        {
        }
    }
}

Pour activer le module HTTP, ajoutez ce qui suit à votre fichier Web. config dans la section System. webServer :To enable the HTTP module, add the following to your web.config file in the system.webServer section:

<system.webServer>
    <modules>
      <add name="BasicAuthHttpModule" 
        type="WebHostBasicAuth.Modules.BasicAuthHttpModule, YourAssemblyName"/>
    </modules>

Remplacez « YourAssemblyName » par le nom de l’assembly (sans l’extension « dll »).Replace "YourAssemblyName" with the name of the assembly (not including the "dll" extension).

Vous devez désactiver d’autres schémas d’authentification, tels que les formulaires ou l’authentification Windows.You should disable other authentication schemes, such as Forms or Windows auth.