| « Google App Engine Java : du JEE en trompe l'oeil... | Google App Engine et JPA : un support limité » |
GAE + GWT + Spring Security = une équation compliquée !
J'avoue, je ne sais pas ce qu'il m'a pris le jour où j'ai décider de sécuriser une application Google App Engine/GWT avec Spring Security. Une envie de nuit blanches, d'interrogations métaphysique et géométrie impossible sans doute... ou tout simplement le bon vieux piège du "je connais, ça va marcher".
Dans mon esprit, cela semblait lumineux : une solution robuste (Spring Security, maintes fois utilisées) pour une application interne business relativement sensible et dont je n'avais pas envie d'assurer l'hébergement.
Pour une fois, je vais essayer de limiter la technique à la portion congrue, les réflexions sur GAE (plus importante que les détails bassement informatiques) seront développées dans le billet suivant.
Et dire qu'en local, ça marche !
Première constatation de taille : ajouter Spring Security à une application GWT/GAE ne présente aucune difficulté. Depuis que GWT 1.6 utilise une arborescence standard, l'utilisation de la librairie Spring est vraiment aisée.
Lancement en local : nickel
Déploiement sur le cloud : La page d'accueil GWT s'affiche d'entrée, en lieu et place de la page de login |-|.
Début des ennuis !
1. Recompilation needed
Un petit coup d'oeil à la console permet de cerner l'origine du problème.
Comme indiqué ici, il manque une classe au support JRE de Google App Engine, utilisée par Spring Security : java.lang.String$CaseInsensitiveComparator
En attendant une correction de part ou d'autre, la seule solution est de recompiler Spring Security en modifiant proprement la classe AbstractAuthenticationToken. Pour ma part, j'ai codé mon propre CaseInsenstiveComparator, basé sur la classe Collator (supportée elle par GAE/J) :
public class StringInsensitiveComparator implements Serializable, Comparator {
private transient Collator col;
public StringInsensitiveComparator() {}
public int compare(Object strA, Object strB ) {
if (col == null)
{
col = Collator.getInstance();
col.setStrength(Collator.PRIMARY);
}
return col.compare(strA, strB );
}
}
La recompilation de Spring Security ne pose pas de problème, et il suffit de remplacer les jar originaux par ceux générés...
2. Savoir lire les petites lignes
Cette fois-ci, pas d'exception dans la console... mais toujours pas de page d'authentification :-/.
J'avoue avoir pas mal buté sur celui là, mais pour la faire courte, la solution... se trouve dans la doc de GAE/J :
"Note: Static files, files that are served verbatim to users such as images, CSS or JavaScript, are handled separately from paths mentioned in the deployment descriptor. A request for a URL path that matches a path to a file in the WAR that's considered a static file will serve the file, regardless of servlet and filter mappings in the deployment descriptor. You can exclude files from those treated as static files using the appengine-web.xml file."
Première (vraie) leçon : sur le cloud, les ressources statiques sont traitées à part. Donc inutile de tenter de les filtrer avec un servlet filter, ça ne marche pas (au passage, les modification suggérées ci-dessus dans le appengine.xml n'ont pas marché) :-(
Ce qui au final s'avère très gênant pour ma solution GWT : ainsi, les pages HTML puis le code Javascript, qui sont le cœur de mon application, étant considérés comme des ressources statiques, elles ne peuvent être prises en charge par le filtre Spring Security. Seuls les appels asynchrones vers le serveurs échouent (puisque l'utilisateur n'est pas authentifié), mais c'est déjà bien tard.
3. Un contournement tiré par les cheveux
Alors, comment duper GAE ? Au final, assez simplement : il suffit de renommer notre page HTML en JSP ! Du coup, elle est filtrée, et les ressources JS ne sont chargées qu'après authentification.
C'est un hack, mais ça marche... en attendant mieux ?
4 commentaires
tout ces posts, ca donne envie de connaitre l'url de l'application ^^
sérieusement, meme si c'est que du test
Thanks for the info on this issue, I managed to get spring security working by amending the source as suggested. If anyone would like a link to the re-compiled core jar I created please feel free to download at: http://www.google-app-engine.com/blog/post/Spring-security-fix-for-google-app-engine.aspx
Jim
Thanks for the info on this issue, I managed to get spring security working by amending the source as suggested. If anyone would like a link to the re-compiled core jar I created please feel free to download at:
http://www.google-app-engine.com/blog/post/Spring-security-fix-for-google-app-engine.aspx
Cet article a 1 réaction en attente de modération...