bence.kovacs
bence.kovacs

Reputation: 53

Multiple sasl authentication mechanisms in Wildfly 24 with Elytron

I've set up Wildfly to use OAUTHBEARER auth mechanism for remote JNDI EJB lookups between my server and a desktop app, and it works great.

However, I also want to set up a simple .properties file based auth method to communicate with the server without a token to be able request one, or access information about the keycloak auth server as i don't want to hardcode it into my client application, and I can't seem to make it work. Whatever I do, the server rejects my auth attempts.

The sample code I was trying to reach the a pre auth bean with looks like this:

private static PreAuth lookUpPreAuthBean() throws NamingException 
{
    final Properties jndiProperties = new Properties();
            
    jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
    jndiProperties.put(Context.PROVIDER_URL,"http-remoting://localhost:8080");
            
    jndiProperties.put(Context.SECURITY_PRINCIPAL, "test");
    jndiProperties.put(Context.SECURITY_CREDENTIALS, "test");
    
    final Context initialContext = new InitialContext(jndiProperties);

    return (PreAuth) initialContext.lookup("ejb:server/server-ejb/PreAuthImpl!co.my.package.server.PreAuth");
}

Here is the stacktrace I get:

    Suppressed: javax.security.sasl.SaslException: ELY05019: No token was given
            at org.wildfly.security.mechanism.oauth2.OAuth2Client.getInitialResponse(OAuth2Client.java:66)
            at org.wildfly.security.sasl.oauth2.OAuth2SaslClient.evaluateMessage(OAuth2SaslClient.java:62)
            at org.wildfly.security.sasl.util.AbstractSaslParticipant.evaluateMessage(AbstractSaslParticipant.java:225)
            at org.wildfly.security.sasl.util.AbstractSaslClient.evaluateChallenge(AbstractSaslClient.java:98)
            at org.wildfly.security.sasl.util.AbstractDelegatingSaslClient.evaluateChallenge(AbstractDelegatingSaslClient.java:54)
            at org.wildfly.security.sasl.util.PrivilegedSaslClient.lambda$evaluateChallenge$0(PrivilegedSaslClient.java:55)
            at java.base/java.security.AccessController.doPrivileged(Native Method)
            at org.wildfly.security.sasl.util.PrivilegedSaslClient.evaluateChallenge(PrivilegedSaslClient.java:55)
            at org.jboss.remoting3.remote.ClientConnectionOpenListener$Capabilities.lambda$handleEvent$1(ClientConnectionOpenListener.java:459)
            at org.jboss.remoting3.EndpointImpl$TrackingExecutor.lambda$execute$0(EndpointImpl.java:991)
            at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
            at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
            at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
            at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
            at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1280)
            at java.base/java.lang.Thread.run(Thread.java:829)
        Suppressed: javax.security.sasl.SaslException: DIGEST-MD5: Server rejected authentication
            at org.jboss.remoting3.remote.ClientConnectionOpenListener$Authentication.handleEvent(ClientConnectionOpenListener.java:760)
            at org.jboss.remoting3.remote.ClientConnectionOpenListener$Authentication.handleEvent(ClientConnectionOpenListener.java:602)
            at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
            at org.xnio.conduits.ReadReadyHandler$ChannelListenerHandler.readReady(ReadReadyHandler.java:66)
            at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:89)
            at org.xnio.nio.WorkerThread.run(WorkerThread.java:591)

If I was to supply a token, the bearer mechanism works, seems like for some reason the other mechanism is not authenticating

Here are the parts from the Wildfly 24 standalone.xml I've modified:

EJB subsystem:

...
<default-security-domain value="other"/>
<application-security-domains>
    <application-security-domain name="other" security-domain="ApplicationDomain"/>
</application-security-domains>
...

Elytron subsystem:

<security-domains>
    <security-domain name="ApplicationDomain" default-realm="JWTRealm" permission-mapper="default-permission-mapper">
        <realm name="JWTRealm" role-decoder="jwt-to-roles"/>
        <realm name="PreAuthRealm" role-decoder="groups-to-roles"/>
    </security-domain>
...
<\security-domains>
<security-realms>
    <identity-realm name="local" identity="$local"/>
    <properties-realm name="PreAuthRealm">
        <users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="PreAuthRealm"/>
        <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
    </properties-realm>
    <token-realm name="JWTRealm" principal-claim="*my claim*">
        <jwt issuer="*my issuer*" audience="account">
           <key kid="*my key id*" public-key="*my public key*"/>
        </jwt>
    </token-realm>
</security-realms>
 <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain">
    <mechanism-configuration>
        <mechanism mechanism-name="OAUTHBEARER">
            <mechanism-realm realm-name="JWTRealm"/>
        </mechanism>
        <mechanism mechanism-name="DIGEST-MD5">
            <mechanism-realm realm-name="PreAuthRealm"/>
        </mechanism>   
    </mechanism-configuration>
</sasl-authentication-factory>

Remoting subsystem:

<subsystem xmlns="urn:jboss:domain:remoting:4.0">
    <http-connector name="http-remoting-connector" connector-ref="default" sasl-authentication-factory="application-sasl-authentication"/>
</subsystem>

The strange part is, if I remove the sasl-authentication-factory="application-sasl-authentication" from the Remoting subsystem, and put back the original security-realm="ApplicationRealm" the above code runs and it actually authenticates me from the .properties file, but then of course the bearer token part won't work, which is the whole point.

What am I missing with my setup here? Is it even possible what i want to achieve?

Upvotes: 2

Views: 1713

Answers (1)

bence.kovacs
bence.kovacs

Reputation: 53

Not a solution, but a workaround. Managed to make it work by not naming the realm "PreAuthRealm" but naming it the default "ApplicationRealm", and for whatever reason setting this realm as the default realm in the security domain makes this, and the JWT realm, work. Setting the "JWTRealm" as default only makes the JWT realm work.

Upvotes: 2

Related Questions