JBoss AS 7 : Remote EJB Authentication Howto

    Hi, I see a lot of post about this, but no answer. The documentation on the topic is quite poor.

    As I succeed to make it work, I share this to help other.

     

    Warning 1 : I'm a newcomer in JBoss, I've started using it at 7.1 beta. I have no clue on how security works on previous version.

    Warning 2 : I don't understand JBoss security, SASL, JAAS, what is used, when and why, with jndi java: or ejb: protocol ? There is really missing a comprehensive guide. I succeed to make it work by gathering some pieces of answer in different thread.

    Warning 3 : I don't garantee that this is the correct way, In fact, I hope this document will get some attention from JBoss expert to finally get the correct answer.

     

    Note : I wasn't able to switch the authentication domain from the client nor application deployment descriptor.

     

    With remote EJB using ejb: protocol

    Edit standalone.xml file.

    In <management> section, add this to existing security realm :

    <security-realm name="MyRealm">

         <authentication>

              <jaas name="MyDomain"/>

         </authentication>

    </security-realm>

     

     

    In section <subsystem xmlns="urn:jboss:domain:security:1.1"><security-domains>, add this follow existing security domain :

    <security-domain name="MyDomain" cache-type="default">

         <authentication>

              <login-module code="Remoting" flag="optional">

                   <module-option name="password-stacking" value="useFirstPass"/>

              </login-module>

              <login-module code="UsersRoles" flag="required">

                   <module-option name="usersProperties" value="file:///${jboss.server.config.dir}/my-users.properties"/>

                   <module-option name="rolesProperties" value="file:///${jboss.server.config.dir}/my-roles.properties"/>

                   <module-option name="defaultUsersProperties" value="file:///${jboss.server.config.dir}/my-users.properties"/>

                   <module-option name="defaultRolesProperties" value="file:///${jboss.server.config.dir}/my-roles.properties"/>

                   <module-option name="password-stacking" value="useFirstPass"/>

              </login-module>

         </authentication>

    </security-domain>

     

    For people interested in using database login :

    <security-domain name="MyDomain" cache-type="default">

         <authentication>

              <login-module code="Remoting" flag="optional">

                   <module-option name="password-stacking" value="useFirstPass"/>

              </login-module>

              <login-module code="Database" flag="required">

                   <module-option name="dsJndiName" value="java:/jdbc/MyDS"/>

                   <module-option name="principalsQuery" value="select passwrd as Password from user where username=?"/>

                   <module-option name="rolesQuery" value="select usergroup as Role, 'Roles' as RoleGroup from user where.username = ?"/>

                   <module-option name="password-stacking" value="useFirstPass"/>

              </login-module>

         </authentication>

    </security-domain>

     

    Finally, modify the security realm in remoting connector configuration :

    <connector name="remoting-connector" socket-binding="remoting" security-realm="MyRealm"/>

     

    And now, on client site, edit jboss-ejb-client.properties add/edit the folowing lines :

    remote.connection.default.callback.handler.class=fr.javatic.my.MyJAASCallbackHandler

    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=true

    remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=JBOSS-LOCAL-USER

    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false

     

    The MyJAASCallbackHandler is to adapt, this is mine :

    ---------------------------------------------------------------------

    import java.io.IOException;

     

    import javax.security.auth.callback.Callback;

    import javax.security.auth.callback.CallbackHandler;

    import javax.security.auth.callback.NameCallback;

    import javax.security.auth.callback.PasswordCallback;

    import javax.security.auth.callback.UnsupportedCallbackException;

    import javax.security.sasl.RealmCallback;

     

    public class MyJAASCallbackHandler implements CallbackHandler {

              private static String s_username;

              private static String s_password;

     

     

              public static void setCredential(String username, String password) {

                             synchronized (MyJAASCallbackHandler .class) {

                                            s_username = username;

                                            s_password = password;

                             }

              }

     

     

              public MyJAASCallbackHandler () {

              }

     

     

              @Override

              public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {

                             synchronized (MyJAASCallbackHandler .class) {

                                            for (Callback current : callbacks) {

                                                           if (current instanceof RealmCallback) {

                                                                          RealmCallback rcb = (RealmCallback) current;

                                                                          String defaultText = rcb.getDefaultText();

                                                                          rcb.setText(defaultText);

                                                           } else if (current instanceof NameCallback) {

                                                                          NameCallback ncb = (NameCallback) current;

                                                                          ncb.setName(s_username);

                                                           } else if (current instanceof PasswordCallback) {

                                                                          PasswordCallback pcb = (PasswordCallback) current;

                                                                          pcb.setPassword(s_password.toCharArray());

                                                           } else {

                           throw new UnsupportedCallbackException(current);

                      }

                                            }

                             }

              }

    }

    ---------------------------------------------------------------------

     

    Finally, in your ear META-INF folder, add jboss-app.xml with this content :

    <jboss-app>

               <security-domain>MyDomain</security-domain>

    </jboss-app>