-
1. Re: LoginModule.login() passed null principal/credential fro
j2ee_junkie Jun 6, 2006 8:28 AM (in response to lost_traveller)Hello, n_bigglewort
First, maybe you could provide some more detail other than it does not work. And please clarify what you mean bywhen JaasSecurityManager.logon() is called from my client loginContext.login();
. Finally, provide some configuration details. Such as, how is "other" security-domain configured, what security-domain is your SLSB using, etc..
thanks, cgriffith -
2. Re: LoginModule.login() passed null principal/credential fro
lost_traveller Jun 6, 2006 9:00 AM (in response to lost_traveller)Hi
Well the client code exists in a Logon Servlet, which retreives the username and password from the user, the client code I posted before is then called in this servlet, to log the user onto the system, debugging this I can see the username and password being correctly passed to the LoginModule implementation inside the PasswordCallback and NameCallback and thus the user logs on correctly. Then, inside the same servelt I do a lookup on an EJB home:InitialContextSingleton initContextFinder = InitialContextSingleton.getInstance(); InitialContext initialContext = initContextFinder.getContext() MyEJBHome ejbHome = initialContext.lookup("java:/comp/env/ejb/MyEJBHome"); ejbHome.create();
At the point where ejbHome.create() is called JBoss invokes the JaasSecurityManager which in turn invokes the logon() method in MyLoginModule (which extends UsernamePasswordLoginModule). At this point the JBoss EJB layer has "forgotten" the username and password used previously.
I have found one solution which seems to be to useHashtable env = new Hashtable(); env.put(Context.SECURITY_PRINCIPAL, "myusername"); env.put(Context.SECURITY_CREDENTIALS, "mypassword"); Context ctx = new InitialContext(env); ctx.lookup("java:/comp/env/ejb/MyEJBHome");
However, our InitialContext is a singleton and cannot be changed, and from what I can work out this way of doing things is out-of-date and no longer fits with the JAAS model.
In my login-config.xml:<application-policy name = "other"> <authentication> <!-- com.me.MyLoginModule simply extends UsernamePasswordLoginModule --> <login-module code = "com.me.MyLoginModule" flag = "required" > </login-module> </authentication> </application-policy>
jobss.xml for the EJB in the session-ejb.jar:<jboss> <security-domain>java:/jaas/other</security-domain> </jboss>
The ejb-jar.xml simply contains roles:... <security-role> <description>View Address Details</description> <role-name>role.address.me.view</role-name> </security-role> <method-permission> <role-name>everyone</role-name> <method> <description>Remote Method: *</description> <ejb-name>AddressSession</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <method> <description>Home Method: *</description> <ejb-name>AddressSession</ejb-name> <method-intf>Home</method-intf> <method-name>*</method-name> </method> </method-permission> ...
-
3. Re: LoginModule.login() passed null principal/credential fro
j2ee_junkie Jun 6, 2006 9:24 AM (in response to lost_traveller)Thanks lost_traveler for more detail. Well right off the bat, I can see a problem with your security domain. You read chapter 8 right? Well the "other" security domain really only needs one Login Module. That would be JBoss' ClientLoginModule. Then create another security domain and put your MyLoginModule in it. Then secure your ejb with the new security domain. Forget about setting env variables. After calling your EJB do a logout of context.
Also note that this login is only good for your Logon Servlet.
Hope this is all helpfull, cgriffith -
4. Re: LoginModule.login() passed null principal/credential fro
lost_traveller Jun 6, 2006 10:08 AM (in response to lost_traveller)Thanks for your replay, yeah I've been using chapter 8 as a guide.
I'm not sure I'm with you though, there is only one login module defined in the "other" domain.
If I modify my code to reflect the following it should work?public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // get front end parameters String username = request.getParameter("username"); String password = request.getParameter("password"); Principal user = null; try { SecurityAssociationHandler handler = new SecurityAssociationHandler(); user = new MyPrincipal(username); handler.setSecurityInfo(user, password.toCharArray()); LoginContext loginContext = new LoginContext("client-login", handler); loginContext.login(); Subject subject = loginContext.getSubject(); Set principals = subject.getPrincipals(); principals.add(user); ... InitialContextSingleton initContextFinder = InitialContextSingleton.getInstance(); InitialContext initialContext = initContextFinder.getContext() AddressSessionHome addressHome = (AddressSessionHome)initialContext.lookup("java:/comp/env/ejb/AddressSessionHome"); AddressSSession addressBean = addressHome.create(); ... loginContext.logout(); } catch(Exception e) { ... } }
where "client-login" is defined in login-cnfig.xml as:<policy> <!-- Used by clients within the application server VM such as mbeans and servlets that access EJBs. --> <application-policy name = "client-login"> <authentication> <login-module code = "org.jboss.security.ClientLoginModule" flag = "required"> <!-- Any existing security context will be restored on logout --> <module-option name="restore-login-identity">true</module-option> </login-module> </authentication> </application-policy> ... </policy>
and jboss.xml should point to a new "ejb-domain", defined as:<application-policy name = "ejb-domain"> <authentication> <!-- com.me.MyLoginModule simply extends UsernamePasswordLoginModule --> <login-module code = "com.me.MyLoginModule" flag = "required" > </login-module> </authentication> </application-policy>
I'm new to JAAS, so how would I then go about keeping a user logged in for an entire session and for authorisation to work for say, session bean to session bean calls?
many thanks. -
5. Re: LoginModule.login() passed null principal/credential fro
lost_traveller Jun 6, 2006 11:04 AM (in response to lost_traveller)ok thanks, still not entirely sure why but changing the LoginContext to use "client-login", worked! My mistake seemed to be to use the same domain for client and server, they should be different one with a client login module and one with a server login module as described in section 8.4.1.
thanks again. -
6. Re: LoginModule.login() passed null principal/credential fro
j2ee_junkie Jun 6, 2006 11:33 AM (in response to lost_traveller)Sorry, I got sidetracked and could not respond quick enough. Yes what you have set up is correct and was what I described. Using "client-login" security domain is a better option than modifing "other". And you added "ejb-domain" as I described.
As mentioned before, the login context you have set up can only be used to authenticate/authorizae(A/A) calls to JBoss in the same thread. This works fine in your scenario to allow your servlet to access an EJB. Since web applications are multi-threaded, with threads being reused from pools, this mechanism should not be used to provide (A/A) for users. In such a case, you would need to create this login context/login/logout for every servlet. The best way to provide user A/A is to use container managed authentication as described in chapter 8.
enjoy, cgriffith -
7. Re: LoginModule.login() passed null principal/credential fro
lost_traveller Jun 7, 2006 8:42 AM (in response to lost_traveller)Well I've been running the secure EJB's with J2EE roles fine now, but like you say it only works for one thread and therefore the login information is lost after that HTTP request/thread dies.
I'm not sure where in chapter 8 is the container managed authentication that you describe? Do you mean securing my servlets by using the <security-constraint> element in web.xml? If so, how does this propagate to the EJB security? Would this mean doing away with using the ClientLoginModule and ServerLoginModules and using a Realm Implementation instead?
Thanks again, I'm working on a very large app and trying to retrofit JBoss complient A/A so that we can use JBoss in the future! -
8. Re: LoginModule.login() passed null principal/credential fro
j2ee_junkie Jun 7, 2006 12:33 PM (in response to lost_traveller)lost_traveller,
Yes, securing your servlets with a security-constraint. As well as configuring an security domain for your servlets. If you use the same security domain for your servlets as your ejb's then security is propagated by the JBossSecurityMgrRealm. In that domain you could use your MyLoginModule. You would not have to use the ClientLoginModule at all. Don't forget to check the wiki pages http://wiki.jboss.org/ and search forums for more help.
cgriffith