1 2 Previous Next 22 Replies Latest reply: Aug 10, 2012 12:05 AM by Veer Muchandi RSS

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

b69 Newbie

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 Knutsen Master

    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

  • 2. Re: Authorizations @RolesAllowed(... @RunAs(..
    b69 Newbie

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

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

    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 Knutsen Master

    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 Newbie

    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 Knutsen Master

    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 Newbie

    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(..
    Veer Muchandi Newbie

    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 Newbie

    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(..
    Dev Mhh Newbie

    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 Newbie

    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(..
    Stephen Coy Master

    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(..
    Veer Muchandi Newbie

    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(..
    Stephen Coy Master

    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