Le blog a été déplacé
Vous pouvez me retrouver sur IT-Signal

vendredi 22 avril 2011

Sécurisation d'une application Flex/Granite DS sur SpringSecurity et Tide

Une application Flex/Java peut utiliser Granite DS/Tide pour simplifier la communication entre les deux tiers de l'application. Spring Security permet la gestion de l'autorisation et de l'authentification. Dans cet article nous allons voir comment utiliser ces deux mécanismes (authentification et autorisation) dans Flex comme si nous étions dans un code Java.

Etablissement du lien entre Flex et Java par Granite DS

La configuration de la communication entre Flex et Java est effectuée grâce à deux fichiers de configuration dans le projet Java :
  • src/main/webapp/WEB-INF/flex/services-config.xml pour la configuration des canaux de communication entre Flex et Java, le lien avec Spring;
  • src/main/webapp/WEB-INF/granite/granite-config.xml pour la configuration de granite et le lien avec Spring Security.
Les configurations (très standard) ont été simplifiées à l'extrême. En effet Granite DS est très bien intégré avec l'écosystème Spring.

Déclaration d'un canal de communication (services-config.xml)

Dans le fichier services-config.xml. Nous allons demander la création d'un service de communication (granite-service) qui s'appuiera sur un canal de communication de type AMF (protocole de communication binaire très efficace d'Adobe) à une adresse précisée dans la configuration :
  • La création du service :
<services>
  <service class="flex.messaging.services.RemotingService" id="granite-service" messagetypes="flex.messaging.messages.RemotingMessage">
   <destination id="spring">
    <channels>
     <channel ref="amf">
    </channel></channels>
    <properties>
     <factory>tideSpringFactory</factory>
     <entitymanagerfactorybeanname>entityManagerFactory</entitymanagerfactorybeanname>
    </properties>
   </destination>
  </service>
 </services>
  • La création du canal :
<channels>
  <channel-definition class="mx.messaging.channels.AMFChannel" id="amf">
   <endpoint class="flex.messaging.endpoints.AMFEndpoint" url="http://{server.name}:{server.port}/{context.root}/amf">
  </endpoint></channel-definition>
 </channels>
Enfin nous allons demander la création d'une factory permettant de créer les objets Java à partir de leurs équivalent Flex. Pour cela nous utilisons un adapteur vers Spring.
<factories>
  <factory class="org.granite.tide.spring.SpringServiceFactory" id="tideSpringFactory">
  </factory>
 </factories>

Configuration de granite (granite-config.xml)

La configuration de granite est encore plus simple. Nous allons juste demander à granite de se configurer avec les annotations dans le code (@RemoteDestination...) et nous lui précisons que la sécurité est gérée par Spring Security ; un adapteur spécifique existe.
<granite-config scan="true">
    <security type="org.granite.spring.security.SpringSecurity3Service">
    </security>
 </granite-config>

Authentification en Flex

Encore une fois le travail est complètement pré-maché par Granite DS. Pour gérer l'utilisateur de l'application Flex, granite met à disposition du programmeur un objet Identity qui permet d'accéder aux informations utiles (données de l'utilisateurs, droits...).
Pour effectuer un login il suffit de faire :
private var __identity:Identity = Identity.instance();
    __identity.login(username, password, onSuccessfulLogin, onFaultLogin);
La méthode effectue exactement la même action que si un utilisateur remplissait un formulaire de login de Spring Security. Les méthodes onSuccessfulLogin et onFaultLogin sont appelée en cas de réussite ou d'échec. Nous pouvons récupérer le nom d'utilisateur avec la méthode suivante :
__identity.username

Autorisation en Flex

Il existe 3 méthodes très utiles sur l'objet Identity permettant de gérer l'autorisation :
  • ifAllGranted : Si l'utilisateur à toutes les autorisations demandées
  • ifAnyGranted : Si l'utilisateur a au moins l'une des autorisations demandées
  • ifNotGranted : Si l'utilisateur n'a pas l'autorisation demandée
Ces méthodes sont asynchrones mais bindable, ce qui permet de les utiliser dans un script mxml :
<mx:button click="updateProduct()" enabled="{dg.selectedItem}" id="bUpdate" label="Update" visible="{identity.hasRole('admin')}"></mx:button>

Ainsi le bouton ne sera visible que pour les administrateurs.
Les appels peuvent aussi être effectués avec un respondeur pour prévoir le prévoir le coté asynchrone de l'appel.
Il existe un cache d'autorisations qui peut être vidé manuellement.

En conclusion

L'utilisation de l'authentification/autorisation est extrêmement simple en Flex, mais parfois un peu limité. Dès qu'un projet à des besoins plus complexes en terme d'autorisation (variabilité en fonction d'un contexte...) il sera nécessaire de s'appuyer sur ces briques de base pour développer un système plus souple.


Article rédigé pour la plateforme de capitalisation technique de Sword