Je travaille actuellement sur une bibliothèque REST pour .net, et j'aimerais avoir des avis sur un point en suspens que j'ai : REST et l'authentification.
Voici un exemple d'une interface RESTful utilisée avec la bibliothèque :
[RestRoot("/user")]
public interface IUserInterface
{
[RestPut("/")]
void Add(User user);
[RestGet("/")]
int[] List();
[RestGet("/get/{id}")]
User Get(int id);
[RestDelete("/delete/{id}")]
void Delete(int id);
}
Le code du serveur se contente alors d'implémenter l'interface et les clients peuvent obtenir la même interface par le biais d'une fabrique. Ou si le client n'utilise pas la bibliothèque, une requête HTTP standard fonctionne également.
Je sais qu'il existe les principaux moyens d'utiliser l'authentification de base HTTP ou d'envoyer un jeton aux demandes nécessitant des utilisateurs authentifiés.
La première méthode (HTTP Basic Auth), présente les problèmes suivants (en partie spécifiques aux navigateurs web) :
- Le mot de passe est transmis à chaque demande - même avec SSL, cela donne une sorte de "mauvais pressentiment".
- Comme le mot de passe est transmis avec un en-tête de demande, il serait facile pour un attaquant local de regarder les en-têtes transmis pour obtenir le mot de passe.
- Le mot de passe est disponible dans la mémoire des navigateurs.
- Pas de moyen standard pour faire expirer les "sessions" des utilisateurs.
- La connexion avec un navigateur interrompt l'aspect et la convivialité d'une page.
Les questions relatives à la deuxième méthode sont davantage axées sur la mise en œuvre et l'utilisation des bibliothèques :
- Chaque URI de demande qui nécessite une authentification doit avoir un paramètre pour le jeton, ce qui est très répétitif.
- Il y a beaucoup plus de code à écrire si l'implémentation de chaque méthode doit vérifier si un jeton est valide.
- L'interface deviendra moins spécifique, par ex.
[RestGet("/get/{id}")]
vs.[RestGet("/get/{id}/{token}")]
. - Où mettre le jeton : à la fin de l'URI ? après la racine ? ailleurs ?
Mon idée était de passer le jeton en tant que paramètre de l'URL comme suit http:/server/user/get/1234?token=token_id
.
Une autre possibilité serait d'envoyer le paramètre en tant qu'en-tête HTTP, mais cela compliquerait l'utilisation avec les clients HTTP ordinaires, je suppose.
Le jeton est renvoyé au client sous la forme d'un en-tête HTTP personnalisé ("X-Session-Id") à chaque demande.
Ceci pourrait alors être complètement abstrait de l'interface, et toute implémentation nécessitant une authentification pourrait simplement demander à quel utilisateur appartient le jeton (s'il est donné).
Pensez-vous que cela violerait trop REST ou avez-vous une meilleure idée ?