Déclencher une authentification basique pour une adresse gérée avec un serveur WebBroker

WebBroker permet de gérer des URL dans le cadre d'une gestion de pages web ou d'API avec Delphi.

Parfois on doit protéger une partie du site web par un user / password à l'ancienne. En authentification basique l'utilisateur et le mot de passe transitent en clair (encodée en BASE64). Bien entendu si on joue à ça le minimum vital pour limiter les risques liés au mot de passe, c'est de le faire sur un site sécurisé par un certificat SSL.

L'activation de la demande d'authentification se fait en retournant un code d'erreur 401 accompagné d'un royaume et du type d'authentification.

Avec WebBroker le code suivant est à mettre dans l'action correspondant à l'URL :

Response.StatusCode := 401;
Response.Realm := 'Espace protégé';
Response.WWWAuthenticate := 'Basic';

Bien entendu il faut l'activer sur toutes les URL devant être protégées avec le même nom d'utilisateur qui sera transmis systématiquement avec chaque page une fois pris en compte.

Une fois le mot de passe rentré par l'utilisateur il sera reçu par le serveur dans Request.Authorization. Il faut donc s'assurer que cette chaîne est remplie et correspond à un vrai user/password ou retourner le code de retour 401.

Request.Authorization contient le type d'authentification demandé suivi par un espace et les informations en BASE64. Dans le cas d'une authentification basique, le nom d'utilisateur et le mot de passe sont séparés de deux points.

Basic cHNldWRvOm1vdGRlcGFzc2U=

pseudo:motdepasse

Pour l'interpréter dans Delphi il faut donc décoder la partie chiffrée et la découper ensuite selon ce qu'on attend. Une fois fait on se retrouve avec un nom d'utilisateur et un mot de passe à vérifier dans notre liste d'utilisateurs autorisés.

Le décodage base64 peut se faire avec l'unité System.NetEncoding :

UserPassword := tnetencoding.base64.decode(Request.Authorization.Substring(6));

UserPassword doit ensuite être découpée en deux ou traitée dans son intégralité selon nos besoins et contraintes.

uses
  System.NetEncoding;

procedure TWebModule1.getUserPassFromAuthorizationString(Authorization: string;
  var user, pass: string);
var
  UserPassDecode: string;
  tab: TArray<string>;
begin
  UserPassDecode := tnetencoding.base64.decode(Authorization.Substring(6));
  tab := UserPassDecode.Split([':']);
  case length(tab) of
    1:
      begin
        user := tab[0];
        pass := '';
      end;
    2:
      begin
        user := tab[0];
        pass := tab[1];
      end;
  else
    user := '';
    pass := '';
  end;
end;

function TWebModule1.UserPasswordValide(Authorization: string): Boolean;
var
  user, pass: string;
begin
  if Authorization.isempty then
    exit(false);

  getUserPassFromAuthorizationString(Request.Authorization, user, pass);

  // tester user/pass

  result := true;
end;

procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
  user, pass: string;
begin
  if not UserPasswordValide(Request.Authorization) then
  begin
    Response.StatusCode := 401;
    Response.Realm := 'Espace protégé';
    Response.WWWAuthenticate := 'Basic';
    exit;
  end;

  getUserPassFromAuthorizationString(Request.Authorization, user, pass);

  Response.Content := '<html>' +
    '<head><title>Application Serveur Web</title></head>' + '<body><p>' +
    Request.Authorization + '</p><p>' + user + ' / ' + pass + '</p></body>' +
    '</html>';
end;

 


Mug carte postale SydneyMug Pascal case in Alexandrie