1 2 Previous Next 22 Replies Latest reply on Aug 10, 2012 12:05 AM by v_m

    Authorizations @RolesAllowed(... @RunAs(..

    b69

      I test my Stateful ejbs with Arquillian. Before adding authorization controls to some methods of those ejbs all JUnit tests passed with success. On adding a security tag like @RolesAllowed(Roles.PROJ_MGR) for instance, no surprise, those methods fail with:

      WARNING:

      1. javax.ejb.AccessLocalException: Client not authorized for this invocation

      Hence I decorated my test class with:

      @RunWith(Arquillian.class)

      @DeclareRoles({Roles.READER, Roles.EDITOR, Roles.PROJ_MGR, Roles.ADMIN})

      @RunAs(Roles.PROJ_MGR)

      @PermitAll

      public class ProjectBeanTest {…

      But the outcome is the same!

      Questions:

      Can Arquillian handle the security tags?

      How to do to make it work? (Beside, the program works as expected when running on an AS with real user logged in!)

      How to tell Arquillian to put the desired role into the session as if an authenticated and authorized user is calling the EJB?

      Any hint is welcome and thanks in advance.

        • 1. Re: Authorizations @RolesAllowed(... @RunAs(..
          aslak

          We currently do not support Security Declarions on the TestCase, but one possible solution is to 'login' in the Test before executing against the Secure EJB.

           

          See the EJB 3.1 Book examples: https://github.com/ALRubinger/oreilly-ejb-6thedition-book-examples/blob/master/ch15-secureschool/src/test/java/org/jboss/ejb3/examples/ch15/secureschool/SecureSchoolIntegrationTest.java

          1 of 1 people found this helpful
          • 2. Re: Authorizations @RolesAllowed(... @RunAs(..
            b69

            Thanks, good to know! I'll try with the indicated login.

            • 3. Re: Authorizations @RolesAllowed(... @RunAs(..
              b69

              I have a question with regard to import of

                   org.jboss.arquillian.prototyping.context.api.ArquillianContext;

              In which jar the ArquillianContext is declared?

              As far as I can see, the examples within the EJB 3.1 book are based on a much older Arquillian / ShrinkWrap version than the ones actually available.

              As ArquillianContext is not available anymore, the groupeId org.jboss.arquillian.prototyping neither exists within Maven Central nor in JBoss Repository.

              The question is, which actual class replace org.jboss.arquillian.prototyping.context.api.ArquillianContex?

              • 4. Re: Authorizations @RolesAllowed(... @RunAs(..
                aslak

                You don't need that..

                 

                Either use @ArquillianResource InitialContext context; or just new InitialContext(). Should be same same in-container

                • 5. Re: Authorizations @RolesAllowed(... @RunAs(..
                  b69

                  Hmm, so if I understood correctly, I would replace:

                  /**

                      * Hook to Arquillian so we can create new JNDI Contexts using supplied properties

                      */

                     @Inject

                     private ArquillianContext arquillianContext;

                  with:

                  @ArquillianResource

                  InitialContext arquillianContext;

                  OK, this compiles. But the line:

                  final Context context = this.arquillianContext.get(Context.class, namingContextProps);

                  Does not!  Due to the compilation error: „The method get(Class<Context>, Map<String,Object>) is undefined for the type InitialContext“.

                  I’m sorry for asking, but others may have the same problem and while I must search fort he reason, you may just know it.

                  Thanks anyway.

                  • 6. Re: Authorizations @RolesAllowed(... @RunAs(..
                    aslak

                    ArquillianContext.get(Context.class) is to get a InitialContext object.

                     

                    by using @ArquillianResource InitialContext you already have one.. so you don't need to use get(Context....)

                    • 7. Re: Authorizations @RolesAllowed(... @RunAs(..
                      b69

                      Hi,

                      I must come back to the problem, because I didn’t find a mean to inject principal and credentials into the session of the secured ejb. For my Tests I used the SecureSchoolIntegrationTest example from A.L. Rubinger mentioned above.

                      I modified the login method to read:

                      private Context login(final String username, final String password) throws NamingException {

                                      // Precondition checks

                                      assert username != null : "username must be supplied";

                                      assert password != null : "password must be supplied";

                       

                                      // Log in and create a context

                                      final Context context = this.arquillianContext;

                                      context.addToEnvironment(Context.SECURITY_PRINCIPAL, username);

                                      context.addToEnvironment(Context.SECURITY_CREDENTIALS, password);

                                      return context;

                      }

                      By this the credentials are known by the arquillianContext, but still unknown by the SessionContext of the bean!

                      I added: “archive.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");”

                      To the JavaArchive created By ShrinkWrap. With this adding the References to the SecureSchool..-  and FireDepartment-EJB are injected by Arquillian. Hence the beans can be accessed, but the security settings inhibit any operation.

                      Just to try with the jndi lookup to setup the bean, I created also a jndi.properties file in the classpath, wherein I declared the SecureSchoolBean as:

                      SecureSchoolBeanLocal=org.jboss.ejb3.examples.ch15.secureschool.impl.SecureSchoolBean

                      The entry exists within the injected arquillianContext, but the lookup fails with NamingException! I tried without understanding, why by this the credentials would eventually have been injected into the SessionContext of the bean. So the question is still open. How to tell the Arquillian test class to run the ejb under test with defined credentials?

                      Thanks for the support.

                      • 8. Re: Authorizations @RolesAllowed(... @RunAs(..
                        v_m

                        Are you successful finding a solution for this issue yet?

                         

                        I have the same issue as yours. The PRINCIPAL and CREDENTIALS are not being passed to the EJB.

                        log.info("Principal: "+ ctx.getCallerPrincipal()); inside the EJB shows anonymous.

                         

                        I am using JBoss 7.1.1. 

                         

                        In the above code we are just adding the username and password to the context. I wonder if arquillian will actually log into the security realm and pull up the roles. For example, if we are using isCallerInRole() inside the EJB, how would that go through?

                        • 9. Re: Authorizations @RolesAllowed(... @RunAs(..
                          b69

                          Hi,

                          good to know others are fighting the same problem.

                          I'm sorry, no, actually I don’t have any solution. It’s an issue of Arquillian or either ShrinkWrap. I postponed the issue, as fighting WebSphere to set up security is of higher priority actually. I have a vague idea in my back mind to start a test thread using concurrent.Future to pass credentials into a self constructed session object and by this circumvent the issue. Of course, I would prefer a @RunAs() annotation, either globally for the test class, or dedicated on every concerned test method, being able by this to test variations of roles. But this should rather come from the developers of Arquillian, I guess, to fit well into the concept. I’ll come back to the issue, as soon as my other targets are running as they should.

                          • 10. Re: Authorizations @RolesAllowed(... @RunAs(..
                            devmhh

                            Hello b69, do you (or somebody else) already have a solution for the problem? @ArquillianResource InitialContext seems like a nice idea but it is not working. And most of our testcases need authorization.

                            • 11. Re: Authorizations @RolesAllowed(... @RunAs(..
                              b69

                              Hi,

                              I’m sorry, not yet. I hope to be back on the problem very soon. I agree fully on the requirement to have proper authorization on test cases. I’ll post as soon I have a solution, or a work around.

                              • 12. Re: Authorizations @RolesAllowed(... @RunAs(..
                                sfcoy

                                Does Testing secured EJBs on JBoss AS7.1.x with Arquillian help at all?

                                 

                                If not maybe we can improve it to deal with your specific problem.

                                • 13. Re: Authorizations @RolesAllowed(... @RunAs(..
                                  v_m

                                  This solution seems to work for the most part. I am stuck with a special case that I am using DatabaseServerLogin instead of UserRolesLogin. Also I am using digest authentication.

                                   

                                  I tried to modify your code for JBossLoginContextFactory as under:

                                   

                                  added this method;

                                  private AppConfigurationEntry createDatabaseModuleConfigEntry() {

                                              Map<String, String> options = new HashMap<String, String>();

                                              options.put("dsJndiName", "java:jboss/datasources/MysqlDS");

                                              options.put("hashAlgorithm", "MD5");

                                              options.put("hashEncoding", "RFC2617");

                                              options.put("hashUserPassword", "false");

                                              options.put("hashStorePassword", "true");

                                              options.put("passwordIsA1Hash", "true");

                                              options.put("storeDigestCallback", "org.jboss.security.auth.callback.RFC2617Digest");

                                              options.put("principalsQuery", "select Password from Principals where PrincipalID=?");

                                              options.put("rolesQuery", "select Role, RoleGroup from Roles where PrincipalID=?");

                                              

                                              

                                              return new AppConfigurationEntry("org.jboss.security.auth.spi.DatabaseServerLoginModule",

                                                      AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, options);

                                          }

                                   

                                  and using this methd as shown below

                                   

                                  @Override

                                          public AppConfigurationEntry[] getAppConfigurationEntry(String name) {

                                              if (!configurationName.equals(name)) {

                                                  throw new IllegalArgumentException("Unexpected configuration name '" + name + "'");

                                              }

                                   

                                   

                                              return new AppConfigurationEntry[] {

                                   

                                   

                                  //            createUsersRolesLoginModuleConfigEntry(),

                                              createDatabaseModuleConfigEntry(),

                                   

                                   

                                              createClientLoginModuleConfigEntry(),

                                   

                                   

                                              };

                                          }

                                   

                                  Now my loginContext.login() method in the test case fails with Caused by: java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: org.jboss.security.auth.callback.MapCallback

                                   

                                  I have no clue on how to resolve this issue. I am guessing that this is due to Digest Authentication. Can you please help me? Please let me know if you need any additional information.

                                  • 14. Re: Authorizations @RolesAllowed(... @RunAs(..
                                    sfcoy

                                    What is it you're trying to test?

                                     

                                    You don't need to use the DatabaseServerLoginModule if all you're doing is testing the behaviour of your EJBs.

                                    1 2 Previous Next