web-dev-qa-db-fra.com

Comment puis-je récupérer les informations d'identification d'authentification de base à partir de l'en-tête?

J'essaie d'écrire quelques tests simples sur le mécanisme d'authentification de l'utilisateur qui utilise l'authentification de base. Comment puis-je récupérer les informations d'identification de l'en-tête?

string authorizationHeader = this.HttpContext.Request.Headers["Authorization"];

Où vais-je d'ici? Il existe plusieurs tutoriels, mais pour la première fois, .NET et l'authentification, pourriez-vous expliquer dans votre réponse étape par étape exactement ce que vous faites et pourquoi.

38
user4041873

De mon blog:

Cela expliquera en détail comment tout cela fonctionne:

Étape 1 - Comprendre l'authentification de base

Chaque fois que vous utilisez l'authentification de base, un en-tête est ajouté à la requête HTTP et ressemble à ceci:

Autorisation: base QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

Source: http://en.wikipedia.org/wiki/Basic_access_authentication

"QWxhZGRpbjpvcGVuIHNlc2FtZQ ==" est simplement "username: password" encodé en Base64 ( http://en.wikipedia.org/wiki/Base64 ). Pour accéder aux en-têtes et autres propriétés HTTP en .NET (C #), vous devez avoir accès au contexte HTTP actuel:

HttpContext httpContext = HttpContext.Current;

Vous pouvez le trouver dans l’espace de noms System.Web.

Étape 2 - Obtenir l'en-tête

L'en-tête d'autorisation n'est pas le seul dans le HttpContext. Pour accéder à l'en-tête, nous devons l'obtenir à partir de la requête.

string authHeader = this.httpContext.Request.Headers["Authorization"];

Si vous déboguez votre code, vous verrez que le contenu de cet en-tête ressemble à ceci:

Base QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

Étape 3 - Vérification de l'en-tête

Vous avez déjà extrait l'en-tête. Il y a plusieurs choses à faire:

  1. Vérifier que l'en-tête n'est pas nul 
  2. Vérifier que le mécanisme d'autorisation/authentification est bien "basique"

Ainsi:

if (authHeader != null && authHeader.StartsWith("Basic")) {
    //Extract credentials
} else {
    //Handle what happens if that isn't the case
    throw new Exception("The authorization header is either empty or isn't Basic.");
}

Maintenant vous avez vérifié que vous avez quelque chose à extraire des données.

Étape 4 - Extraction des informations d'identification

Retrait de la sous-chaîne "de base"

Vous pouvez maintenant essayer d'obtenir les valeurs pour nom d'utilisateur et mot de passe. Tout d'abord, vous devez vous débarrasser de la sous-chaîne "Basic". Vous pouvez le faire comme ça:

string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();

Voir les liens suivants pour plus de détails:

  1. http://msdn.Microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx
  2. http://msdn.Microsoft.com/en-us/library/t97s7bs3(v=vs.110).aspx

Décodage en base64

Nous devons maintenant décoder de Base64 en chaîne:

//the coding should be iso or you could use ASCII and UTF-8 decoder
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));

Maintenant le nom d'utilisateur et le mot de passe seront dans ce format:

username:password

Fractionnement Nom d'utilisateur: Mot de passe

Pour obtenir le nom d'utilisateur et le mot de passe, nous pouvons simplement obtenir l'index du ":"

int seperatorIndex = usernamePassword.IndexOf(':');

username = usernamePassword.Substring(0, seperatorIndex);
password = usernamePassword.Substring(seperatorIndex + 1);

Vous pouvez maintenant utiliser ces données pour les tests. Bonne chance!

PS: le code final peut ressembler à ceci:

HttpContext httpContext = HttpContext.Current;

string authHeader = this.httpContext.Request.Headers["Authorization"];

if (authHeader != null && authHeader.StartsWith("Basic")) {
    string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
    Encoding encoding = Encoding.GetEncoding("iso-8859-1");
    string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));

    int seperatorIndex = usernamePassword.IndexOf(':');

    var username = usernamePassword.Substring(0, seperatorIndex);
    var password = usernamePassword.Substring(seperatorIndex + 1);
} else {
    //Handle what happens if that isn't the case
    throw new Exception("The authorization header is either empty or isn't Basic.");
}
155
Dawid O

Super réponse de @DawidO.

Si vous cherchez simplement à extraire les crédits d'authentification de base et comptez sur la magie .NET si vous avez HttpContext, cela fonctionnera également:

  public static void StartListener() {
    using (var hl = new HttpListener()) {
      hl.Prefixes.Add("http://+:8008/");
      hl.AuthenticationSchemes = AuthenticationSchemes.Basic;
      hl.Start();
      Console.WriteLine("Listening...");
      while (true) {
        var hlc = hl.GetContext();

        var hlbi = (HttpListenerBasicIdentity)hlc.User.Identity;
        Console.WriteLine(hlbi.Name);
        Console.WriteLine(hlbi.Password);

        //TODO: validater user
        //TODO: take action
      }
    }
  }
3
sobelito

N'oubliez pas que l'utilisation de chaînes peut être moins sécurisée. Ils resteront en mémoire jusqu'à ce qu'ils soient choisis par GC.

0
Anup Thakare