WildFly 13 remote ejb call failure
sergiu_pienar Jul 20, 2018 2:52 AMI'm trying to build an EJB remote client for calling an EJB deployed to a WildFly 13 server.
The class is the one below:
public class RemoteEjb { public static void main(final String[] args) throws Exception { // Invoke a stateless bean // RemoteEjb.invokeStatelessBean(); AuthenticationConfiguration ejbConfig = AuthenticationConfiguration.empty() .setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("DIGEST-MD5")).useRealm("autoidRealm").useName("admin") .usePassword("admin"); // create your authentication context AuthenticationContext context = AuthenticationContext.empty().with(MatchRule.ALL.matchHost("127.0.0.1"), ejbConfig); // create a callable that invokes an EJB Callable callable = () -> { // create an InitialContext Properties properties = new Properties(); properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory"); properties.put(Context.PROVIDER_URL, "remote+http://127.0.0.1:8080"); InitialContext ctx = new InitialContext(properties); // look up an EJB and invoke one of its methods (same as before) CACCustomCodeRemote remote = (CACCustomCodeRemote)ctx .lookup("java:jboss/exported/sixD-all-5.4.1.4/sixD-all-ejbs/CACCustomCodeBean!com.viagents.business.customcode.CACCustomCodeRemote"); List results = remote.queryByClientAndJarName(-1L, "sixD-dashboard-helpers.jar"); if (results != null && results.size() > 0) { System.out.println(results.size()); } return null; }; // use your authentication context to run your callable context.runCallable(callable); }
This fails with
Suppressed: javax.security.sasl.SaslException: DIGEST-MD5: Server rejected authentication at org.jboss.remoting3.remote.ClientConnectionOpenListener$Authentication.handleEvent(ClientConnectionOpenListener.java:736) at org.jboss.remoting3.remote.ClientConnectionOpenListener$Authentication.handleEvent(ClientConnectionOpenListener.java:578)
I'm attaching my standalone-full.xml in case someone wants to have a look.
In the standalone-full.xml I'm defining a custom security domain, named autoidDomain, that uses a custom login class.
That legacy domain is being exported to elytron using the elytron-integration tags, that define a legacy realm.
Inside the elytron subsystem I'm defining a legacy domain that is linked to that exported domain. Also inside the elytron subsystem I've defined a sasl-authentication-factory that should be using that legacy domain. There are two mechanisms defined inside that legacy-sasl-authentication: PLAIN and DIGEST-MD5.
I'm also attaching my remoting.log - in the first case, when I'm using directly the "autoidRealm" - the one defined in the legacy security system I'm getting
Server sending authentication rejected: javax.security.sasl.SaslException: ELY05087: Client selected realm not offered by server (autoidRealm)
that is, the server doesn't "show" the realm defined inside the legacy security subsystem.
When I change in my client
useRealm("autoidRealm")
to
useRealm("legacyRealm")
(i.e. the one exported from the legacy security system to elytron)
I`m getting
Server sending authentication rejected: javax.security.sasl.SaslException: ELY05051: Callback handler does not support credential acquisition [Caused by org.wildfly.security.auth.callback.FastUnsupportedCallbackException: javax.security.auth.callback.PasswordCallback@25446d8d] at org.wildfly.security.mechanism.digest.PasswordDigestObtainer.getSaltedPasswordFromPasswordCallback(PasswordDigestObtainer.java:295) at org.wildfly.security.mechanism.digest.PasswordDigestObtainer.handleUserRealmPasswordCallbacks(PasswordDigestObtainer.java:112) at org.wildfly.security.sasl.digest.AbstractDigestMechanism.handleUserRealmPasswordCallbacks(AbstractDigestMechanism.java:195) at org.wildfly.security.sasl.digest.DigestSaslServer.validateDigestResponse(DigestSaslServer.java:264) at org.wildfly.security.sasl.digest.DigestSaslServer.evaluateMessage(DigestSaslServer.java:363) at org.wildfly.security.sasl.util.AbstractSaslParticipant.evaluateMessage(AbstractSaslParticipant.java:199) at org.wildfly.security.sasl.digest.DigestSaslServer.evaluateResponse(DigestSaslServer.java:336) at org.wildfly.security.sasl.util.AuthenticationCompleteCallbackSaslServerFactory$1.evaluateResponse(AuthenticationCompleteCallbackSaslServerFactory.java:58) at org.wildfly.security.sasl.util.AuthenticationTimeoutSaslServerFactory$DelegatingTimeoutSaslServer.evaluateResponse(AuthenticationTimeoutSaslServerFactory.java:106) at org.wildfly.security.sasl.util.SecurityIdentitySaslServerFactory$1.evaluateResponse(SecurityIdentitySaslServerFactory.java:59) at org.xnio.sasl.SaslUtils.evaluateResponse(SaslUtils.java:245) at org.xnio.sasl.SaslUtils.evaluateResponse(SaslUtils.java:217) at org.jboss.remoting3.remote.ServerConnectionOpenListener$AuthStepRunnable.run(ServerConnectionOpenListener.java:486) at org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:926) at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35) at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
I've changed the sasl mechanism to SCRAM-SHA-1 (to presumably match my custom login module that is using the SHA algorithm with Base64 encoding) in both the sasl-mechanism definition from standalone-full.xml and my client and now I'm getting:
2018-07-19 17:43:18,463 TRACE [org.jboss.remoting.remote.server] (default task-1) Server sending authentication rejected: javax.security.sasl.SaslException: ELY05161: Unable to retrieve password for "admin" at org.wildfly.security.mechanism._private.MechanismUtil.getPasswordCredential(MechanismUtil.java:141) at org.wildfly.security.mechanism.scram.ScramServer.evaluateInitialResponse(ScramServer.java:205) at org.wildfly.security.sasl.scram.ScramSaslServer.evaluateMessage(ScramSaslServer.java:84)
Later edit:
Added the wildfly-elytron sources to my app and did some debugging. Inside MechanismUtil.getPasswordCredential I'm getting:
userName: admin callbackHandler: org.wildfly.security.sasl.util.TrustManagerSaslServerFactory passwordType: org.wildfly.security.password.interfaces.ScramDigestPassword passwordAlgorithm: scram-sha-1 providers: org.wildfly.security.sasl.scram.ScramSaslServerFactory
Went a bit further down the debug line today and found that from org.wildfly.security.mechanism._private.MechansimUtil.handleCallbacks(ElytronMessages log, CallbackHandler callbackHandler, Callback... callbacks) the flow is -> org.wildfly.security.auth.server.ServerAuthenticationContext -> handleOne(final Callback[] callbacks, final int idx) -> the callback is an instance of CredentialCallback thus entering
getCredential(final Class credentialType, final String algorithmName, final AlgorithmParameterSpec parameterSpec)
which delegates to
org.jboss.as.security.elytron.SecurityDomainContextRealm$PicketBoxBasedIdentity
I'm 90% sure this is a configuration issue between the legacy and the elytron system so I'll be more than happy to accept suggestions.
Thanks!
-
standalone-full.xml.zip 8.2 KB
-
remoting.log.zip 2.1 KB