Bonjour,
Je rencontre de grosse difficulté à mettre en place un système d'EJB3 sécurisé via JAAS. Sachant que toute mes données utilisateur sont dans une "base" LDAP.
Pour info: j'utilise JBOSS-4.2.1-GA sous Linux avec NetBeans 5.5 comme IDE.
Mon application EJB est accessible via une servlet, cette dernière reçoit les requêtes HTTP et selon les paramètres et la session elle sait quoi faire.
Tel que j'ai compris le concept j'ai implémenté ceci, pour la requête login:
- la servlet utilise une méthode appellée login
- à l'intèrieur, elle va appeller une méthode de classe qui va authentifier le user/pass (donné en paramètre). Cette méthode renvoit un LoginContext:
"monapp" renvoyant à la configuration application-policy correspondante, celle ci appelle le module org.jboss.security.auth.spi.LdapExtLoginModule avec les bons paramètres qu'il faut pour LDAP...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 public static LoginContext authenticate(String username, String password) { UsernamePasswordHandler handler = new UsernamePasswordHandler(username, password.toCharArray()); LoginContext lc = null; try { lc = new LoginContext("monapp", handler); lc.login(); } catch (LoginException ex) { ex.printStackTrace(); return null; } return lc; }
- si le LoginContext renvoyé est différent de null alrs je charge mon EJB :
- à la requete suivante, je fais bêtement:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 Context context = new InitialContext(); AppRemoteIFace app = (AppRemoteIFace)context.lookup("appli/app/remote"); //et je met app dans la session http, mais là déjà j'imagine que c'est pas la bonne chose à faire, si? HttpSession session = req.getSession(); session.setAttribute(SESSION_APP_BEAN, app);
Le problème:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 AppRemoteIFace as = (appRemoteIFace)getFromSession(req, SESSION_APP_BEAN); try { app.foo(); } catch (Exception e) { System.err.println("app.foo failed"); e.printStackTrace(); }
le login se passe bien, il utilise bien le module, l'authentification passe etc... Et si je test app.foo() dans la foulée ça fonctionne bien, (ou app.fooAdmin(), si l'utilisateur n'a pas le role admin: j'ai bel est bien une exception du au manque de droits etc...)
MAIS: à la requête suivante, impossible de lancer app.foo() ou autre, on dirait que l'EJB perd le contexte et qu'il sait pas quoi faire.
Le seul hack tout moche qui résout ça:
avant app.foo(); et là ça fonctionne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 SecurityAssociation.setPrincipal(new SimplePrincipal((String)getFromSession(req, SESSION_USERNAME))); SecurityAssociation.setCredential((String)getFromSession(req, SESSION_PASSWORD));
Mais je sais que c'est pas la bonne manière, il y a quelque chose qui m'échappe. Ai-je oublié quelque chose côté EJB? C'est plus que probable, voilà le code:
Et les deux interfaces:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 @Stateless public class App implements AppRemoteIFace, AppLocalIFace { @RolesAllowed({"admin"}) public String fooAdmin() { return "fooAdmin"; } @RolesAllowed({"user"}) public String foo() { return "foo"; } }
et:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 @Remote public interface AppRemoteIFace { public String fooAdmin(); public String foo(); }
Je suis perdu.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 @Local public interface AppLocalIFace { public String fooAdmin(); public String foo(); }
Le gros soucis que j'ai c'est aussi de trouver de la bonne documentation à jour, je trouve des tas d'exemples complet pour ejb2 mais pas ejb3 (or il y a de sacrées différences!). Si vous en avez à me proposer qui parle d'un exemple identique (ejb3+jaas+ldap ça "devrait être" assez commun non?) je suis preneur.
Merci de votre aide!
Partager