6 Replies Latest reply on Aug 22, 2013 7:41 AM by peterfry

    IronJacamar Oracle Reauthentication support

    ricardoarguello

      Anybody interested in helping me test this?

       

      https://github.com/rarguello/ironjacamar-oracle-reauth

       

      --

      Ricardo Arguello

        • 1. Re: IronJacamar Oracle Reauthentication support
          jesper.pedersen

          Hi Richardo, feel free to submit the plugin once it is done. Then I'll include it in our distributions.

           

          Thanks for working on this

          • 2. Re: IronJacamar Oracle Reauthentication support
            ricardoarguello

            Hi Jesper,

             

            I'm working on a fork on GitHub, so I can send you a Pull Request.

            Should I create an issue on Jira?

            • 3. Re: IronJacamar Oracle Reauthentication support
              jesper.pedersen

              Yes, please - feature request / JDBC. Then submit a pull request with the JIRA number in the commit message, and note on the pull request that is the code is submitted under the MIT license.

               

              Keep the license header - verify with "ant checkstyle".

               

              Thanks !

              • 4. Re: IronJacamar Oracle Reauthentication support
                ricardoarguello

                I created this issue:

                 

                [JBJCA-1068] Oracle Reauthentication plugin

                https://issues.jboss.org/browse/JBJCA-1068

                 

                And this Pull Request:

                 

                https://github.com/ironjacamar/ironjacamar/pull/49

                 

                Thanks!

                • 5. Re: IronJacamar Oracle Reauthentication support
                  jesper.pedersen

                  This will be in 1.1.0.Final - thanks again.

                  • 6. Re: IronJacamar Oracle Reauthentication support
                    peterfry

                    Is there a test case for this component. I am trying to support Oracle Proxy Authentication on EAP 6.0.1 but without any joy. My main stumbling block is the configuration of the security section of the datasource:

                     

                    <subsystem xmlns="urn:jboss:domain:datasources:1.1">

                     

                    <xa-datasource jndi-name="java:jboss/datasources/someDS" pool-name="java:jboss/datasources/someDS_Pool">

                    <datasources>

                    <xa-datasource-property name="URL"> jdbc:oracle:thin:@%DATABASE_HOST%:%DATABASE_PORT%:%DATABASE_SID%

                     

                     

                    <xa-pool>

                     

                    <is-same-rm-override>false</is-same-rm-override>

                     

                    <no-tx-separate-pools>true</no-tx-separate-pools>

                     

                    </xa-pool>

                     

                    <security>

                    <!--<user-name>USERNAME</user-name>

                    <password>PASSWORD</password>

                    <reauth-plugin class-name="org.me.OracleReauthPlugin"/>-->

                     

                    <security-domain>demo</security-domain>

                     

                    </security>

                     

                    <validation>

                     

                    <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleValidConnectionChecker"/>

                     

                    <stale-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleStaleConnectionChecker"/>

                     

                    <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.oracle.OracleExceptionSorter"/>

                     

                    </validation>

                     

                    </xa-datasource>

                     

                    <drivers>

                     

                    <driver name="oracle" module="com.oracle">

                     

                    <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>

                     

                    </driver>

                     

                    </drivers>

                     

                    </datasources>

                     

                    </subsystem>

                    </xa-datasource-property>

                     

                    <driver>oracle</driver>

                     

                    I have added a security domain

                     

                    <subsystem xmlns="urn:jboss:domain:security:1.2">
                            <security-domains>
                                    <security-domain name="other" cache-type="default">
                                        <authentication>
                                            <login-module code="Remoting" flag="optional">
                                                <module-option name="password-stacking" value="useFirstPass"/>
                                            </login-module>
                                            <login-module code="RealmDirect" flag="required">
                                                <module-option name="password-stacking" value="useFirstPass"/>
                                            </login-module>
                                        </authentication>
                                    </security-domain>
                                    <security-domain name="jboss-web-policy" cache-type="default">
                                        <authorization>
                                            <policy-module code="Delegating" flag="required"/>
                                        </authorization>
                                    </security-domain>
                                    <security-domain name="jboss-ejb-policy" cache-type="default">
                                        <authorization>
                                            <policy-module code="Delegating" flag="required"/>
                                        </authorization>
                                    </security-domain>
                                    <security-domain name="brms" cache-type="default">
                                        <authentication>
                                            <login-module code="UsersRoles" flag="required">
                                                <module-option name="usersProperties" value="${jboss.server.config.dir}/brms-users.properties"/>
                                                <module-option name="rolesProperties" value="${jboss.server.config.dir}/brms-roles.properties"/>
                                            </login-module>
                                        </authentication>
                                    </security-domain>
                                    <!-- Introduced for demonstrating Oracle Proxy Authentication -->
                        <security-domain name="demo" cache-type="default">
                           <authentication>
                              <login-module code="SimpleUsers" flag="sufficient">
                                    <module-option name="username" value="USERNAME"/>
                                    <module-option name="password" value="PASSWORD"/>
                              </login-module>
                              <login-module code="UsersRoles" flag="sufficient">
                                    <module-option name="usersProperties" value="${jboss.server.config.dir}/demo-users.properties"/>
                                                <module-option name="rolesProperties" value="${jboss.server.config.dir}/demo-roles.properties"/>
                              </login-module>
                           </authentication>
                        </security-domain>               
                    </security-domains>
                    </subsystem>

                     

                    I'm then running a arquillian test

                     

                    import java.security.PrivilegedAction;
                    import java.sql.SQLException;
                    import java.util.logging.Level;
                    import java.util.logging.Logger;

                    import javax.ejb.EJB;
                    import javax.security.auth.Subject;
                    import javax.security.auth.login.LoginContext;
                    import javax.security.auth.login.LoginException;

                    import org.jboss.arquillian.container.test.api.Deployment;
                    import org.jboss.arquillian.junit.Arquillian;
                    import org.jboss.arquillian.secureejb.JBossLoginContextFactory;
                    import org.jboss.arquillian.secureejb.demo.SecurityRoles;
                    import org.jboss.shrinkwrap.api.ShrinkWrap;
                    import org.jboss.shrinkwrap.api.asset.EmptyAsset;
                    import org.jboss.shrinkwrap.api.spec.WebArchive;
                    import org.junit.Test;
                    import org.junit.runner.RunWith;

                    import org.me.TestEjb;

                    @RunWith(Arquillian.class)
                    public class OracleReauthPluginTest {

                    private static final Logger logger = Logger.getLogger(OracleReauthPluginTest.class.getName());

                        @EJB
                        private TestEjb testEjb;

                        @Deployment
                        public static WebArchive createTestArchive() {
                            WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war")
                                    .addClasses(JBossLoginContextFactory.class, SecurityRoles.class, TestEjb.class)
                                    .addAsWebInfResource("META-INF/ejb-jar.xml").addAsWebInfResource("META-INF/jboss-ejb3.xml")
                                    .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml").addAsResource("users.properties")
                                    .addAsResource("roles.properties");
                            return webArchive;
                        }

                        @Test
                        public void testAuthorisedSecureOperation() throws LoginException {
                            LoginContext loginContext = JBossLoginContextFactory.createLoginContext("user1", "password");
                            loginContext.login();
                            try {
                                Subject.doAs(loginContext.getSubject(), new PrivilegedAction<Void>() {

                                    @Override
                                    public Void run() {
                                     try {
                         testEjb.performSecureOperation();
                       } catch (SQLException e) {
                         logger.log(Level.SEVERE, "EJB oepration failed", e);
                       }
                                        return null;
                                    }

                                });
                            } finally {
                                loginContext.logout();
                            }
                        }
                    }

                     

                    With the logon context being supplied by

                     

                    package org.jboss.arquillian.secureejb;

                    import java.io.IOException;
                    import java.util.HashMap;
                    import java.util.Map;

                    import javax.resource.spi.security.PasswordCredential;
                    import javax.security.auth.Subject;
                    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.auth.login.AppConfigurationEntry;
                    import javax.security.auth.login.Configuration;
                    import javax.security.auth.login.LoginContext;
                    import javax.security.auth.login.LoginException;

                    /**
                    * Provides a {@link LoginContext} for use by unit tests. It is driven by users.properties and roles.properties files as
                    * described in <a href="https://community.jboss.org/wiki/UsersRolesLoginModule">UsersRolesLoginModule</a>
                    */
                    public class JBossLoginContextFactory {

                        static class NamePasswordCallbackHandler implements CallbackHandler {
                            private final String username;
                            private final String password;

                            private NamePasswordCallbackHandler(String username, String password) {
                                this.username = username;
                                this.password = password;
                            }

                            public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
                                for (Callback current : callbacks) {
                                    if (current instanceof NameCallback) {
                                        ((NameCallback) current).setName(username);
                                    } else if (current instanceof PasswordCallback) {
                                        ((PasswordCallback) current).setPassword(password.toCharArray());
                                    } else {
                                        throw new UnsupportedCallbackException(current);
                                    }
                                }
                            }
                        }

                        static class JBossJaasConfiguration extends Configuration {
                            private final String configurationName;

                            JBossJaasConfiguration(String configurationName) {
                                this.configurationName = configurationName;
                            }

                            @Override
                            public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
                                if (!configurationName.equals(name)) {
                                    throw new IllegalArgumentException("Unexpected configuration name '" + name + "'");
                                }

                                return new AppConfigurationEntry[] {

                                createUsersRolesLoginModuleConfigEntry(),

                                createClientLoginModuleConfigEntry(),

                                };
                            }

                            /**
                             * The {@link org.jboss.security.auth.spi.UsersRolesLoginModule} creates the association between users and
                             * roles.
                             *
                             * @return
                             */
                            private AppConfigurationEntry createUsersRolesLoginModuleConfigEntry() {
                                Map<String, String> options = new HashMap<String, String>();
                                return new AppConfigurationEntry("org.jboss.security.auth.spi.UsersRolesLoginModule",
                                        AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
                            }

                            /**
                             * The {@link org.jboss.security.ClientLoginModule} associates the user credentials with the
                             * {@link org.jboss.security.SecurityContext} where the JBoss security runtime can find it.
                             *
                             * @return
                             */
                            private AppConfigurationEntry createClientLoginModuleConfigEntry() {
                                Map<String, String> options = new HashMap<String, String>();
                                options.put("multi-threaded", "true");
                                options.put("restore-login-identity", "true");

                                return new AppConfigurationEntry("org.jboss.security.ClientLoginModule",
                                        AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);
                            }
                        }

                        /**
                         * Obtain a LoginContext configured for use with the ClientLoginModule.
                         *
                         * @return the configured LoginContext.
                         */
                        public static LoginContext createLoginContext(final String username, final String password) throws LoginException {
                            final String configurationName = "Arquillian Testing";

                            CallbackHandler cbh = new JBossLoginContextFactory.NamePasswordCallbackHandler(username, password);
                            Configuration config = new JBossJaasConfiguration(configurationName);
                            Subject subject = new Subject();
                            PasswordCredential credential = new PasswordCredential(username,  password.toCharArray());
                           
                            subject.getPrivateCredentials().add(credential);
                            return new LoginContext(configurationName, subject, cbh, config);
                        }

                    }

                     

                    The problem I have is that in BaseWrapperManagedConnectionFactory.SubjectActions.run() the subject has no private credentials.

                     

                    Is the approach I'm taking (in terms of setting up an integration test) correct? I am hacking around with this.