Sécuriser une application Flex BlazeDS avec le SSO d’Active Directory
Votre RSSI vous demande d’intégrer vos applications Flex/BlazeDS à Active Directory ? Vous pourriez le faire via le protocole LDAP, mais pourquoi ne pas offrir plus de confort à vos utilisateurs en leur évitant de taper une énième fois leur mot de passe ? Faites-vous aimer de vos utilisateurs en intégrant votre application au SSO natif d’Active Directory !
Intéressons-nous à une application web disposant d’une partie client codée en Flex, qui communique avec les services métier par le biais d’un canal BlazeDS. Avant de pouvoir utiliser ces services par le biais de l’interface Flex, les utilisateurs doivent s’authentifier avec leur compte Active Directory. Cet article expose la manière de rendre l’authentification transparente en tirant profit du protocole de SSO Kerberos intégré à Active Directory.
L’idéal serait de laisser BlazeDS se débrouiller seul avec Kerberos, malheureusement hors de la sempiternelle combinaison login/mot de passe, le mécanisme d’authentification de BlazeDS est totalement perdu. Mais comme un canal BlazeDS, ça reste un web-service Java, profitons des capacités de ce dernier ! Entre alors Spring Security.
Le framework Spring Security fournit aux applications Java un panel de manières de gérer l’authentification. Depuis sa version 3, la configuration du framework en xml est devenue assez simple. Et, joie, Spring Security supporte Kerberos par le biais d’un module récent. Tous les composants de notre architecture sont maintenant identifiés, reste à les faire communiquer.
Architecture
Le diagramme suivant résumé les interactions entre les différents modules applicatifs qui permettent à l’extension Kerberos de Spring Security pour protéger le canal BlazeDS en SSO.
Kerberos et Active Directory
Publié par le MIT dans les années 80, le protocole Kerberos est le mode d’authentification par défaut sous Active Directory depuis Windows 2000. Il remplace le protocole NTLM qui n’est plus recommandé par Microsoft.
Le fonctionnement de Kerberos est basé sur des échanges de tickets avec un contrôleur de domaine. Le schéma suivant représente l’enchaînement d’opérations mis en œuvre lorsqu’un poste client tente d’accéder à un service protégé par Kerberos :
- (1) L’utilisateur ouvre sa session Windows en s’authentifiant avec son mot de passe Active Directory.
- (2) Le poste de travail récupère alors auprès du contrôleur de domaine un ticket dit TGT (Ticket Granting Ticket).
- (3) Lorsque l’utilisateur veut accéder à un service qui requiert une authentification Kerberos, Windows demande au contrôleur de domaine de lui fournir un ST (Service Ticket) pour le service précisé. Le ST est chiffré, et seul le service possède la clé de déchiffrement.
- (4)Le contrôleur de domaine remet au poste client un Service Ticket, valable uniquement pour le service spécifié.
- (5)Le poste client peut alors s’authentifier auprès du service, sans demander son mot de passe à l’utilisateur.
Pour identifier le service demandé et générer le Service Ticket adéquat, le contrôleur de domaine identifie les services par leur Service Principal Name (SPN). Chaque service est enregistré comme un compte utilisateur Active Directory. A partir de ces comptes, le contrôleur de domaine génère au préalable à toute authentification la clé qui permettra au service de valider les Service Tickets envoyés par les clients, et l’associe à un SPN donné en paramètre de l’outil ktpass qui génère les clés. Dans le cas d’un service web, notre SPN est de la forme HTTP/serveur-app.octo.com@DOMAINE-AD.
Le service accédé dans notre architecture sera bien entendu la partie serveur de notre application Flex. Voyons comment intégrer cette dernière au système d’authentification Kerberos.
Configuration de BlazeDS
Spring Security s’intègre à BlazeDS grâce au projet Spring-Flex, malheureusement ce support se limite actuellement aux authentifications de type utilisateur/mot de passe. Impossible donc de profiter des facilités de Spring-Flex pour l’authentification par SSO. La solution alternative que nous avons mise en place est détaillée ci-dessous.
Nous utilisons les filtres Spring Security sur les URLs pour protéger deux types de ressources :
- Les ressources statiques de l’application (html, css, …), et notamment le fichier .swf qui forme la partie cliente de l’application
- L’endpoint BlazeDS (le côté serveur du canal BlazeDS)
Le fichier de configuration de Spring Security se présente alors comme suit :
<sec:http entry-point-ref="spnegoEntryPoint" auto-config="false">
<sec:intercept-url pattern="/**" access="IS_ AUTHENTICATED_FULLY" />
<sec:custom-filter ref="spnegoAuthenticationProcessingFilter" position="BASIC_AUTH_FILTER" />
</sec:http>
La ligne intercept-url exige que l’utilisateur soit authentifié. La ligne custom-filter précise que l’authentification se fera par le protocole SPNego (voir ci-dessous).
Lors de l’accès du navigateur à une de ces URLs, Spring Security déclenche l’authentification et déclenche des échanges suivant le protocole SPNego. SPNego est un protocole qui permet de négocier le mode d’authentification utilisé (par exemple NTLM ou Kerberos) en fonction des capacités communes au client et au serveur. La négociation se matérialise par une réponse HTTP (code 401) de la part du serveur d’application, qui contient les headers SPNego précisant que le serveur supporte Kerberos.
Une fois que le navigateur et le serveur se sont accordés sur l’utilisation du protocole Kerberos, le navigateur utilise l’API Windows pour demander au contrôleur de domaine un Service Ticket pour le serveur d’applications. Le ticket est ensuite validé par l’extension Kerberos de Spring Security en utilisant la clé de service créée précédemment par le contrôleur de domaine.
Si le ticket est validé, l’utilisateur est authentifié et les mécanismes d’habilitation (Rôles, ACLs) de Spring Security entrent en jeu pour autoriser ou refuser l’accès à une ressource donnée. Les habilitations sont totalement indépendantes de Kerberos.
Petite surprise offerte BlazeDS : l’utilisation d’un channel HTTPs avec BlazeDS (SecureAMFEndpoint) impose d’utiliser un mécanisme de login matérialisé côté serveur par une classe LoginCommand. Nous avons donc implémenté notre propre LoginCommand (PreAuthLoginCommand) qui... n’effectue aucune vérification, l’authentification ayant déjà été effectuée par Spring Security/Kerberos.
public class PreAuthLoginCommand implements LoginCommand, LoginCommandExt {
public Principal doAuthentication(String username, Object credentials) {
//On n’effectue aucune verification !
logger.info("doAuthentication " + username + ", returning a PreAuthPrincipal");
return new PreAuthPrincipal(username);
}
public boolean doAuthorization(Principal principal, List arg1) {
logger.info("doAuthorization " + principal + ", returning true");
return true;
}
…
}
Pour aller plus loin
Cet article passe sous silence la configuration du poste client. Elle est très simple et se résume en deux points :
- Utiliser un navigateur compatible avec SPNego et Kerberos (Internet Explorer, Firefox et Chrome le sont)
- Indiquer au navigateur que votre application est un site de confiance, et qu’à ce titre il est autorisé à lui transmettre des tickets Kerberos. Cette configuration peut être déployée sur un parc de machines en utilisant les stratégies de groupe (GPO) d’Active Directory
Pour plus de détails, voyez la section « Références » ci-dessous.
Une idée pour terminer et peaufiner la sécurité de votre application : offrez à vos utilisateurs la possibilité de se dé-logger de la session Kerberos et repasser à une authentification par mot de passe, pour permettre à un autre utilisateur que le détenteur du compte Active Directory de s’authentifier.
Références
- La documentation de l’intégration Spring-Security/BlazeDS, qui ne fonctionne que pour une authentification de type utilisateur/mot de passe : http://static.springsource.org/spring-flex/docs/1.5.x/reference/html/#security
- The Spring Security Kerberos extension: http://static.springsource.org/spring-security/site/extensions/krb/index.html
- The extension's manual (including Internet Explorer configuration) : http://blog.springsource.com/2009/09/28/spring-security-kerberos/
- A guide to enable Kerberos in Firefox : http://grolmsnet.de/kerbtut/firefox.html
- A guide to enable Kerberos in Chrome : https://sites.google.com/a/chromium.org/dev/developers/design-documents/http-authentication