Récemment, une question est tombée sur la liste de diffusion MVP concernant l’authentification au niveau du service pour le Service Relais, les publications dans les Topics et les souscriptions.
Je me permets donc de vous faire un petit résumé dans ce billet (issue de la discussion ainsi que du post de Brent Stineman que vous pouvez lire ici)
Pour ceux qui utilise le service bus depuis longtemps, vous avez déjà dû utiliser le portail Access Control Service pour configurer vos droits d’authentification au service bus. Le lien pour accéder à ce portail ACS était accessible depuis les informations de connexion au niveau global de votre espace de nom de service bus.
Les informations de connexion ouvraient la popup suivante :
où l’on distingue un lien pour ouvrir le portail de gestion ACS.
Désormais, lors de la création d’un nouvel espace de nom de Service Bus, par défaut la fonctionnalité ACS n’est pas disponible et les informations de connexion sont donc réduites à une Shared Access Signature:
Pourquoi plus d’ACS ?
Plusieurs raison ont amené ce changement :
Tout d’abord, les équipes MS ont pu remarquer que pour une grande majorité de namespace, seul les informations de connexion principale (owner) étaient utilisées. Pour rappel, ce compte est en quelques sortes un compte administrateur du namespace et il n’est pas du tout judicieux de le communiquer et de l’utiliser dans l’ensemble de ses applications. Il faut toujours crée d’autres comptes et affecter les droits adéquates (Manage, Send, Listen)
Ensuite, ces informations sont des informations de connections à l’ACS. Le service bus quant à lui consomme des Tokens d’identifications. Lorsque vous utiliser l’ACS, vous avez donc besoin d’un premier appel pour valider votre authentification et vous voir délivrer un token par l’ACS et ensuite appeler le Service Bus (Topic/Queue/Subscription) avec ce Token pour envoyer/recevoir des messages. Il y a donc 2 appels, un pour l’authentification et un pour l’exécution. Si vous ne mettez pas en cache le token reçu (ce qui est fait avec certains SDK), 2 appels sont effectués à chaque opérations, ce qui amène une latence dans votre application et diminue les performances du service bus d’environ 2000msg/s à près de 40 msg/sec.
Cependant un point positif de l’ACS est que nous pouvions gérer des utilisateurs et par conséquent révoquer des autorisations à distance en supprimant un utilisateur de l’ACS. Ses informations de connections devenant alors invalides. Ce point est moins trivial avec les SAS mais une technique assez simple permet cependant de s’en rapprocher.
Délivrer un jeton de connexion
En effet, la clé d’accès partagé va nous permettre de générer une clé valable pour une durée temporaire que nous pouvons alors distribuer au client applicatif. (Si vous utiliser déjà les SAS pour les comptes de stockage, le principe est le même)
Nous allons donc voir comment générer cette SAS et comment l’utiliser coté client.
Coté serveur, nous avons besoin de générer une SAS :
var runtimeUri = ServiceBusEnvironment.CreateServiceUri("sb", sbNamespace, path); var sasString = SharedAccessSignatureTokenProvider.GetSharedAccessSignature(keyName, sharedAccessKey, runtimeUri.ToString(), new TimeSpan(0, 60, 0));
avec les paramètres suivants:
- sbNamespace : namespace du service bus
- path: le nom partiel ou complet des entités auxquel vous donnez accès (String.Empty permet l’accès au namespace, “test-“ donnera accès à toutes les entités commençant par “test-”
- keyName : nom de la règle de stratégie d’accès partagé
- sharedAccessKey : clé primaire ou secondaire de la stratégie d’accès partagé
- new Timespane(0,60,0) : est le paramètre pour la gestion de l’expiration de la clé.
Vous retrouvez les informations de connexions dans la partie Configurer de votre service bus :
cela vous donner une chaine de caractère de ce type :
“SharedAccessSignature sr=sb%3a%2f%2ftestblog.servicebus.windows.net%2f&sig=XB4XGy4%2b1YaLgFoCsRjs%2fxyoYYX7RYG1meE1nV%2fPWR4%3d&se=1409355633&skn=test”
Ce token peut alors est utilisé par l’application cliente pendant une durée de 1h.
Utiliser le jeton de connexion
Coté client, il suffit de crée un tokenProvider utilisant le jeton précédemment généré et l’utiliser dans la MessagingFactory.
var tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider(sasString); var SasFactory = MessagingFactory.Create(runtimeUri, tokenProvider); var SasClientTopic = SasFactory.CreateTopicClient("TestTopic"); SasClientTopic.Send(new BrokeredMessage("Test Message"));
Expiration d’une stratégie
La révocation à distance d’un token pourrait se faire en supprimant la stratégie associe au niveau du portail, cependant contrairement à la gestion de compte pour l’ACS, vous êtes limité à la création de 12 stratégies au niveau namespace et 12 au niveau topics. On ne peut donc pas créer une stratégie par client applicatif lorsque nous sommes dans un scénario complexe.
On peut cependant tout à fait imaginer avoir une API Web sécurisé permettant de délivrer des tokens valables pour une durée limité et à charge du client de faire la demande d’un nouveau token lorsque celui-ci devient invalide.
Et si j’ai vraiment besoin d’un ACS pour l’instant ?
Il est toujours possible de créer un nouveau namespace à l’aide des commandlets powershell New-AzureSBNamespace en passant le paramètre supplémentaire suivant “-useAcs true”.
Cela pourra éventuellement vous dépanner, Microsoft gardant encore sous le coude l’ACS pour des raisons de compatibilité pour les clients. Mais sachez qu’il est préférable de réfléchir au SAS pour des raisons de performances et également car l’ACS migrera un jour ou l’autre. (On suppose facilement vers le service d’authentification d’Azure WAAD, mais sous combien de temps ….)
Pingback: L’authentification fédérée par claims, les grands principes | Nouvelles Chroniques d'Amethyste