13 Replies Latest reply on Oct 13, 2012 7:34 AM by kieselhorst

    ClientLoginModule support

    thammoud

      Hello,

       

      We are migrating from JBOSS 4.x to 7.1.1. A client is trying to access a remote EJB. Previously, code like below worked by propogating the credentials to the server:

       

      LoginContext lc = new LoginContext("client-login", new UsernamePasswordHandler(userName, password.toCharArray()));

      lc.login();

       

      ....

       

      InitialContext ctx = new InitialContext(...);

      Server s = ctx.lookup();

      s.invoke();

       

      With 7.1.1, we are basically doing the same:

       

      LoginContext lc = new LoginContext("client-login", new UsernamePasswordHandler(userName, password.toCharArray()));

      lc.login();

       

      ......

       

      jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");

      jndiProps.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");

      jndiProps.put("jboss.naming.client.ejb.context", true);

      jndiProps.put("jboss.naming.client.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");

                

      Context ctx = new InitialContext(jndiProps); <<=== Throws exception

       

      Caused by: javax.security.sasl.SaslException: Cannot get userid/password [Caused by javax.security.auth.callback.UnsupportedCallbackException]

                at com.sun.security.sasl.ClientFactoryImpl.getUserInfo(ClientFactoryImpl.java:157)

                at com.sun.security.sasl.ClientFactoryImpl.createSaslClient(ClientFactoryImpl.java:94)

                at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities$1.run(ClientConnectionOpenListener.java:352)

                at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities$1.run(ClientConnectionOpenListener.java:350)

                at java.security.AccessController.doPrivileged(Native Method)

                at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:350)

                at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.handleEvent(ClientConnectionOpenListener.java:214)

                at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)

                at org.xnio.channels.TranslatingSuspendableChannel.handleReadable(TranslatingSuspendableChannel.java:189)

                at org.xnio.channels.TranslatingSuspendableChannel$1.handleEvent(TranslatingSuspendableChannel.java:103)

                at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:72)

                at org.xnio.nio.NioHandle.run(NioHandle.java:90)

                at org.xnio.nio.WorkerThread.run(WorkerThread.java:184)

                at ...asynchronous invocation...(Unknown Source)

                at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:270)

                at org.jboss.remoting3.EndpointImpl.doConnect(EndpointImpl.java:251)

                at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:349)

                at org.jboss.remoting3.EndpointImpl.connect(EndpointImpl.java:333)

                at org.jboss.naming.remote.client.EndpointCache$EndpointWrapper.connect(EndpointCache.java:105)

                at org.jboss.naming.remote.client.NamingStoreCache.getRemoteNamingStore(NamingStoreCache.java:55)

                ... 8 more

       

       

      We would like to avoid having to sepcify the credentials as part of the InitialContext properties. Any help will be greatly appreciated.

       

      Thank you

      Tarek Hammoud

        • 1. Re: ClientLoginModule support
          wdfink

          You can not use the InitialContext with properties like this ATM.

          Have a look to the AS7 documentation here.

          You may use the ejb-client api direct.

          • 2. Re: ClientLoginModule support
            thammoud

            Thanks Wolf,

             

            When I add:

             

            jndiProps.put(Context.SECURITY_PRINCIPAL, "foo");

            jndiProps.put(Context.SECURITY_CREDENTIALS, "bar");

             

            the code works properly. However, I do not want to specify the credentials in the hash table and want the context factory to use the credentials as set by my:

             

            LoginContext lc = new LoginContext("client-login", new UsernamePasswordHandler(userName, password.toCharArray()));

            lc.login();

             

            From the link you provided, I do not see any references to JAAS. I still see username/password hardcodes as properties.

            • 3. Re: ClientLoginModule support
              thammoud

              Excuse me for misstating the real issue. We do not care about the JNDI lookup not being hardcoded with  security details. We want the freedom to invoke the EJB using the ClientLoginModule. It looks like Sasl Client setup does not take the credentials as set by ClientLoginModule into account. Is this supported? This worked just fine in 4.x and 6.x. I saw remote.connection.default.callback.handler.class property but could not find a CallBackHandler to  simply read what was setup by ClientLoginModule. I must be missing something.

               

              public class TestRemoteReference {

               

                  public static void main(String[] args) {

                      try {

                         Properties jndiProps = new Properties();

                         jndiProps.put(Context.PROVIDER_URL,"remote://localhost:4447");

               

                         jndiProps.put(Context.SECURITY_PRINCIPAL,   "username");

                         jndiProps.put(Context.SECURITY_CREDENTIALS, "password");                     

                         jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");

               

                         Context ctx = new InitialContext(jndiProps);

               

                         Properties clientProp = new Properties();

                         clientProp.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");

                         clientProp.put("remote.connections", "default");

                         clientProp.put("remote.connection.default.port", "4447");

                         clientProp.put("remote.connection.default.host", "localhost");

              //           clientProp.put("remote.connection.default.username", "username");

              //           clientProp.put("remote.connection.default.password", "password");

                         clientProp.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");

                         clientProp.put("remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");

                         clientProp.put("remote.connection.default.callback.handler.class", "org.jboss.security.auth.callback.JASPICallbackHandler");

               

               

                         EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(clientProp);

                         ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);

                         EJBClientContext.setSelector(selector);                                

               

                         Service service = (Service) ctx.lookup("XXX"); // No issues here

               

               

                         // Local login as another user. Hoping that SASL will somehow pick these

                         // credentials up before invocation

               

                         // Client login module gets called and sets up the

                         // the correct principal in SecurityAssociationActions.

               

               

                         LoginContext c = SecurityUtils.login("client-login", "username2", "password2");

               

                         // Fails witht he dreaded "No EJB receiver available" but the real exception is a security

                         // Exception. If we uncomment the security info in the remote connection properties, it works fine

               

               

                         Object result = service.doSomething()

                      }

                      catch(Throwable ex) {

                          ex.printStackTrace();           

                      }

                  }

              }

               

               

              login.conf

              client-login {

                 org.jboss.security.ClientLoginModule  required

                        ;

              };

               

              • 4. Re: ClientLoginModule support
                dlofthouse

                No the ClientLoginModule is not supported on the client side for setting credentials.

                1 of 1 people found this helpful
                • 5. Re: ClientLoginModule support
                  thammoud

                  Hi Darran,

                   

                  Will it be? What alternative methods do you suggest we use to achieve such a basic requirement?

                   

                  Thanks

                  • 6. Re: ClientLoginModule support
                    dlofthouse

                    Not for the scenario you are talking about, that we are planning seperately to allow a second authentication after a connection has been established.  For the ClientLoginModule feel free to raise a feature request and we can consider it for the opening of the original connection but as I say we are taking a higher level look at the re-authentication issue on an existing connection.

                    • 7. Re: ClientLoginModule support
                      thammoud

                      Darran,

                       

                      Do you have an existing jira issure for the " re-authentication issue on an existing connection."?

                      • 8. Re: ClientLoginModule support
                        wdfink

                        Tarek,

                        at the moment the credentials are used to establish the connection and can not be changed for this. Also the connection is handled transparent (if you do not use the EjbClient API direct and handle it), it will be closed by GC (finalizer) if you remove all references.

                        The ejb-client (and the server) is optimized for such connections, instead of using multiple connections (AS4/5) only one connection is used and the requests go through the same connection.

                        Therefor the authentication and behaviour (e.g. threading) are different.

                         

                        There is a possiblility to have more than one connection and select the connection/user from the app-code, I can provide an example if needed.

                        • 9. Re: ClientLoginModule support
                          thammoud

                          Hi Wolf,

                           

                          I would appreciate the example. This is a major rewrite in our application of what has been working for the past 8 years. A bit troublesome is that EJB authentication on the server side does work with the ClientLoginModule. 

                           

                          With 7.x, there is now a big difference on how local vs remote ejb's are invoked. In local mode, security context can be propogated using ClientLoginModule. Unlike remote calls. EJB invocations should be consistent and they now feel worlds apart. While all the optimizations in the remoting layer are appreciated, taking away thread-set-credentials in remote calls will undeniably cause a lot of headaches for developers. Just my 2 cents.

                           

                          Tarek

                          • 10. Re: ClientLoginModule support
                            kieselhorst

                            Any news on this? I'd also appreciate an example.

                             

                            Regards

                            Dennis

                            • 11. Re: ClientLoginModule support
                              jaikiran

                              Tarek, you have raised 2 questions/issues here:

                               

                              1) How to use ClientLoginModule on the remote client side to propagate a client side JAAS login information to the server during connection authentication

                              2) Once a remote connection has been established with the server using a specific credential, how to switch the credential on that remote connection, for subsequent usages of that connection.

                               

                              #2 is currently not possible and that's what Darran meant when he said work is in progress to try and support it.

                               

                              However, if you are looking for an example on how to do #1 then I just added an example to the quickstart guides here https://github.com/jaikiran/quickstart/tree/client-login-module/ejb-remote. You can run that quickstart to see it working. But you can even read the javadoc on this class and the referenced classes to understand how it all works https://github.com/jaikiran/quickstart/blob/client-login-module/ejb-remote/client/src/main/java/org/jboss/as/quickstarts/ejb/remote/client/callbackhandler/CustomServerLoginHandshakeCallbackHandler.java#L40.

                               

                              I won't be able to write up an article on this today but plan to do soon. But I guess, those javadoc should give you can idea of how it can be achieved. If you have further questions, feel free to ask.

                              • 12. Re: ClientLoginModule support
                                thammoud

                                Hi Jaikiran,

                                 

                                I kind of worked around 1 but with a serious kludge which involved caching various InitialContexts based on credentials. Your method is most definitley more elegant. Thank you for putting the time in this. One thought that kept coming back is with the whole notion of "fixing" the credentials at connection establishment time and effectively do away with credential propogation at call time. I do see why to a certain extent and reworked our code to work with this model. You guys truly do a fantastic job. Please keep it up.

                                • 13. Re: ClientLoginModule support
                                  kieselhorst

                                  Thank you for the example. Which JIRA issue is dealing with #2?