Nous avons un service qui gère l'autorisation basée sur un nom d'utilisateur et un mot de passe. Au lieu de faire partie du nom d'utilisateur et du mot de passe de l'appel, nous le plaçons dans l'en-tête SOAP.Quels sont les problèmes potentiels avec ce schéma de sécurité WebService?
Dans un scénario typique, un service Web appelle le service d'autorisation au début de l'exécution pour vérifier que l'appelant est autorisé à l'appeler. Le problème est cependant que certains de ces services Web s'appellent les uns les autres, et cela signifie qu'à chaque sous-appel, les autorisations de l'utilisateur sont vérifiées, ce qui peut être très coûteux.
Ce que je pensais faire était d'avoir le service d'autorisation retourner un jeton de sécurité après le premier appel. Ensuite, au lieu de devoir appeler le service d'autorisation à chaque fois, le service Web peut valider l'en-tête de sécurité localement.
L'en-tête de sécurité ressemble à ceci (code C# - parés pour illustrer le concept essentiel):
public sealed class SecurityHeader : SoapHeader
{
public string UserId; // Encrypted
public string Password; // Encrypted; Just realized this field isn't necessary [thanks CJP]
public DateTime TimeStamp; // Used for calculating header Expiry
public string SecurityToken;
}
L'idée générale est que le SecurityHeader est vérifié à chaque appel. Si elle existe, n'a pas expiré et que SecurityToken est valide, la méthode Web se poursuit normalement. Sinon, il retournera une erreur, ou il tentera de réautoriser et de générer un nouveau SecurityHeader
Le SecurityToken est basé sur un hachage salé de UserId, Password et TimeStamp. Le sel est changé tous les jours pour éviter les rejets. Le seul problème que je vois est qu'un utilisateur peut avoir l'autorisation d'accéder au service Web A, mais pas au service Web B. S'il appelle A et reçoit un jeton de sécurité, cela signifie que B le lui permettra à travers s'il utilise le même jeton. Je dois le changer afin que le jeton de sécurité ne soit valide que du service Web au service Web, plutôt que du service Web à l'utilisateur. Cela devrait être OK si l'utilisateur appelle A qui appelle B, mais pas OK si l'utilisateur appelle le service A puis le service D. Un moyen de contourner cela consiste à affecter une clé commune (ou un ensemble de clés) à des services logiquement liés. (c'est-à-dire si le client peut faire A, alors logiquement il peut aussi faire B).
Sinon, je devrais encoder l'ensemble du jeu d'autorisations de l'utilisateur dans le cadre de l'en-tête de sécurité. Je vais devoir enquêter sur ce que seront les frais généraux.
Edit:
Plusieurs personnes ont mentionné la recherche d'autres régimes de sécurité comme WS-Security et SAML etc. Je l'ai déjà. En fait, j'ai eu l'idée de WS-Security. Le problème est que d'autres systèmes ne fournissent pas la fonctionnalité dont j'ai besoin (mise en cache des informations d'autorisation et protection contre les rejets sans base de données intermédiaire). Si quelqu'un connaît un régime qui fait alors je serai heureux de l'utiliser à la place. En outre, c'est pas à propos de l'authentification. Cela est géré par un autre mécanisme indépendant de mon contrôle.
S'il s'avère qu'il n'y a aucun moyen de mettre en mémoire cache les données d'autorisation, cela signifie que je n'aurai qu'à supporter le surcoût d'autorisation à chaque niveau.
Une assertion SAML ressemble à ceci: "Le client X a des rôles A et B. Cette assertion est valide au fil du temps T. Signé, AuthService." Comment est-ce que ce n'est pas ce dont vous avez besoin? – ykaganovich
Je vais revoir SAML et XACML aujourd'hui. – ilitirit