6 Replies Latest reply on Mar 27, 2017 8:22 AM by benze

    Passing credentials in EJB invocation from a different ear

    jewellgm

      Hello,

       

      I am trying to upgrade an application from JBoss AS 7.1.1 to WildFly 8.2.0.  We have an architecture where ear1 contains some beans that are secured with methods invocation allowable if the caller has the proper credentials.  A second ear (ear2) gets credentials from an external source and tries to invoke methods on the secure beans in ear1.  However, I have been unable to get WildFly to recognize the credentials that I am trying to utilize.  As a result, all invocations fail with an error stating that the caller isn't authorized, and that the principal is null.

       

      Since the invocation is happening across ears, I am using the remote interface on the secured beans.  I have tried setting the Context.SECURITY_PRINCIPAL and Context.SECURITY_CREDENTIALS parameters within the InitialContext, I have tried using the proprietery EJB client context (which we really don't want to use anyway), and I have even tried a hack to change the SecurityContextAssociation that is used when the invocation occurs.  Regardless, the result is always the same:  authorization fails with a null principal.

       

      How do I invoke a secure (remote) EJB with specific credentials for valid accounts specified in a security domain?  Using the $local authentication isn't an option, because I need to check the credentials that I receive from the external source.

       

       

      Thank you!

        • 1. Re: Passing credentials in EJB invocation from a different ear
          jewellgm

          Here's a code snippet:

           

          Properties properties = new Properties();

          properties.put(SECURITY_PRINCIPAL, username);

          properties.put(SECURITY_CREDENTIALS, credentials);

          Context context = new InitialContext(properties);

          RemoteEJB ejb = (RemoteEJB) context.lookup(remoteName);

          ejb.doSomething();

           

          And here's what I see in the log after the call to doSomething():

           

          2015-04-22 09:12:26,664 TRACE [org.jboss.security.audit] (default task-17) [Failure]Source=org.jboss.security.plugins.javaee.EJBAuthorizationHelper;Action=authorization;Resource:=[org.jboss.security.authorization.resources.EJBResource:contextMap={policyRegistration=null}:method=public abstract void com.test.RemoteEJB.doSomething():ejbMethodInterface=Remote:ejbName=RemoteEJB:ejbPrincipal=null:MethodRoles=Roles(guest):securityRoleReferences=null:callerSubject=Subject:

              Principal: anonymous

          :callerRunAs=null:callerRunAs=null:ejbRestrictionEnforcement=false:ejbVersion=2.0];Exception:=PBOX000017: Acces denied: authorization failed ;policyRegistration=null;

          • 2. Re: Passing credentials in EJB invocation from a different ear
            jewellgm

            Does invoking a secured bean from a web application change the manner in which credentials must be presented?  I've got a class inside a war file which is neither an EJB or a servlet, that attempts to invoke a secured bean.  I've attempted passing in credentials in a number of ways, and the TRACE level logging in org.jboss.security indicates that the user is validated, but the principal information that is passed to the secured bean is always "null".  This causes an EJBAccessException to be thrown.

             

            I'm seeing this behavior in both WildFly 8.2.0 and WildFly 9.0.0 Beta 2.

             

            Any help would be appreciated.  This has been a very frustrating few weeks with security issues.

            • 3. Re: Passing credentials in EJB invocation from a different ear
              jewellgm

              I've verified that the Subject contained in my LoginContext is correct.  It has the correct username and all roles assigned that account.  When I make the following call sequence:

               

              PasswordClientCallbackHandler handler = new PasswordClientCallbackHandler(username, "TestRealm", password.toCharArray());

              LoginContext loginContext = new LoginContext("TestAuth", handler);

              loginContext.login();

              Subject subject = loginContext.getSubject();

              Subject.doAs(subject, new PrivilegedAction<Object>() {

                  public Object run() {

                      InitialContext ic = new InitialContext();

                      TestBean ejb = (TestBean) ic.lookup(beanName);

                      return ejb.doSomething();

                  }

              });

               

              It appears as if the subject being passed into the call is null.  Here's the message that I see in the log:

               

              2015-04-28 10:41:42,344 DEBUG [org.jboss.security] (default task-17) PBOX000292: Insufficient method permissions [principal: null, EJB name: TestBean, method: doSomething, interface: Remote, required roles: Roles(AUTHORIZED_USER), principal roles: Roles(), run-as roles: null]

               

              As I mentioned previously, this code is being executed inside a Web context.  I don't know if that matters.

              • 4. Re: Passing credentials in EJB invocation from a different ear
                jewellgm

                I *may* have found the solution.  It appears that the security context is intentionally not being propagated between the web context and the ejb context.  I discovered this article:

                 

                https://docs.jboss.org/author/display/WFLY8/EE+Concurrency+Utilities

                 

                which suggests using the new concurrent utilities that are part of Java EE 7.  I'll give them a shot tomorrow...

                • 5. Re: Passing credentials in EJB invocation from a different ear
                  jewellgm

                  I suppose I shouldn't be surprised, but using the concurrency utilities yielded the exact same results.  Here's the relevant code:

                   

                  LoginContext loginContext = null;
                  try {
                  PasswordClientCallbackHandler handler = new PasswordClientCallbackHandler(username, "TestRealm", password.toCharArray());
                  loginContext = new LoginContext("TestAuth", handler);
                  loginContext.login();
                  Callable<PermissionSeqType> task = new Callable<PermissionSeqType>() {
                  public PermissionSeqType call() {
                  Object result = null;

                  try {

                  InitialContext ic = new InitialContext();

                  TestBean ejb = (TestBean) ic.lookup(beanName);

                  ic.close();

                  result = ejb.doSomething();
                  } catch (Exception e) {
                  logger.error(e);
                  }
                  return result;
                  }
                  };
                  try {
                  Callable<Object> contextualTask = getContextService().createContextualProxy(task, Callable.class);
                  Future<Object> future = getManagedExecutorService().submit(contextualTask);
                  result = future.get();
                  } catch (Exception e) {
                  logger.error(e);
                  }
                  loginContext.logout();
                  } catch (LoginException e) {
                  throw new RemoteException("LoginException occurred", e);
                  }

                   

                  The eventual call to future.get() shows another EJBAccessException, and the TRACE level logging in org.jboss.security shows that the principal passed is null rather than the principal used in the LoginContext.login() call.

                   

                  Does anybody at RedHat actually look at these forums?  I'm getting very frustrated with this because I've been struggling with it for almost two weeks now, and there hasn't been a single response.  Am I doing something wrong?  Is WildFly security just broken?  I don't even know whether I should submit a bug report because nobody seems to be able to tell me if I'm doing something wrong.

                  • 6. Re: Passing credentials in EJB invocation from a different ear
                    benze

                    Hi Greg,

                    Did you ever manage to resolve this? I'm running into a similar issue, but in my car is the security domain which is always null.

                     

                    I was wondering what you did to resolve this, if you remember.

                     

                    Thanks

                     

                    Eric