user name does not propagate with programmatic authentication
cgiordano Feb 28, 2018 1:07 PMI am migrating my ejb application to Wildfly 11 from Wildfly 9, attempting to use elytron. I find that when I use the wildfly-config.xml file for my ejb client all works as expected. When I try to do the same programmatically (without wildfly-config.xml) I find that the user name does not appear in the security context. I need the user name in the security context because we use spring security for method parameter authorization. The wildfly-config.xml that is used successfully is:
<configuration>
<authentication-client xmlns="urn:elytron:1.0">
<authentication-rules>
<rule use-configuration="default-config"/>
</authentication-rules>
<authentication-configurations>
<configuration name="default-config">
<set-user-name name="aeinstein"/>
<credentials>
<clear-password password="e=mc2"/>
</credentials>
<sasl-mechanism-selector selector="DIGEST-MD5"/>
<providers>
<use-service-loader />
</providers>
</configuration>
</authentication-configurations>
</authentication-client>
</configuration>
The code snippet I use to invoke a remote ejb that does not propagate the user name to the security context is as follows:
private <T> T locate(Class<T> clz) {
String userName = "aeinstein";
String password = "e=mc2";
AuthenticationConfiguration common = AuthenticationConfiguration
.empty()
.setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("DIGEST-MD5"))
.useName(userName)
.usePassword(password);
final AuthenticationContext authCtx = AuthenticationContext.empty().with(MatchRule.ALL.matchHost("localhost"), common);
Callable<T> vCallable = () -> {
final Properties jndiProperties = new Properties();
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL, "remote+http://localhost:8080");
final Context context = new InitialContext(jndiProperties);
String beanName = clz.getSimpleName() + "Bean";
String url = "ejb:paragon2/paragon2-server-side/" + beanName + "!" + clz.getName();
return (T)context.lookup(url);
};
try {
return authCtx.runCallable(vCallable);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
The server.log entries:
2018-02-28 12:42:18,664 TRACE [org.wildfly.security] (default I/O-8) Handling MechanismInformationCallback type='SASL' name='JBOSS-LOCAL-USER' host-name='127.0.0.1' protocol='remote'
2018-02-28 12:42:18,664 TRACE [org.wildfly.security] (default I/O-8) Handling MechanismInformationCallback type='SASL' name='JBOSS-LOCAL-USER' host-name='127.0.0.1' protocol='remote'
2018-02-28 12:42:18,665 TRACE [org.wildfly.security] (default I/O-8) Creating SaslServer [org.wildfly.security.sasl.localuser.LocalUserServer@34c3a4d3] for mechanism [JBOSS-LOCAL-USER] and protocol [remote]
2018-02-28 12:42:18,665 TRACE [org.wildfly.security] (default I/O-8) Created SaslServer [org.wildfly.security.sasl.util.SecurityIdentitySaslServerFactory$1@258d3e6->org.wildfly.security.sasl.util.AuthenticationTimeoutSaslServerFactory$DelegatingTimeoutSaslServer@65a3bd5b->org.wildfly.security.sasl.util.AuthenticationCompleteCallbackSaslServerFactory$1@7493f38f->org.wildfly.security.sasl.localuser.LocalUserServer@34c3a4d3] for mechanism [JBOSS-LOCAL-USER]
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Handling NameCallback: authenticationName = $local
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Principal assigning: [$local], pre-realm rewritten: [$local], realm name: [local], post-realm rewritten: [$local], realm rewritten: [$local]
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Role mapping: principal [$local] -> decoded roles [] -> realm mapped roles [SuperUser] -> domain mapped roles [SuperUser]
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Authorizing principal $local.
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Authorizing against the following attributes: [] => []
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Permission mapping: identity [$local] with roles [SuperUser] implies ("org.wildfly.security.auth.permission.LoginPermission" "") = true
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Authorization succeed
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) RunAs authorization succeed - the same identity
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Handling AuthorizeCallback: authenticationID = $local authorizationID = $local authorized = true
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Handling AuthenticationCompleteCallback: succeed
2018-02-28 12:42:18,677 TRACE [org.wildfly.security] (default task-100) Handling SecurityIdentityCallback: identity = SecurityIdentity{principal=$local, securityDomain=org.wildfly.security.auth.server.SecurityDomain@1d6152a7, authorizationIdentity=EMPTY, realmInfo=RealmInfo{name='local', securityRealm=org.wildfly.security.auth.realm.SimpleMapBackedSecurityRealm@3e3dff44}, creationTime=2018-02-28T17:42:18.677Z}
Here the user name appears as $local. If I use wildfly-config.xml, the user name is aeinstein. Where have I gone wrong?
Below are the server.log entries for a successful remote ejb call using wildfly-config.xml (The code path appears very different.)
2018-02-28 13:01:05,264 TRACE [org.wildfly.security] (default I/O-12) Handling MechanismInformationCallback type='SASL' name='DIGEST-MD5' host-name='127.0.0.1' protocol='remote'
2018-02-28 13:01:05,265 TRACE [org.wildfly.security] (default I/O-12) Handling MechanismInformationCallback type='SASL' name='DIGEST-MD5' host-name='127.0.0.1' protocol='remote'
2018-02-28 13:01:05,265 TRACE [org.wildfly.security] (default I/O-12) Handling AvailableRealmsCallback: realms = [ApplicationRealm]
2018-02-28 13:01:05,265 TRACE [org.wildfly.security] (default I/O-12) Creating SaslServer [org.wildfly.security.sasl.digest.DigestSaslServer@52c9104d] for mechanism [DIGEST-MD5] and protocol [remote]
2018-02-28 13:01:05,265 TRACE [org.wildfly.security] (default I/O-12) Created SaslServer [org.wildfly.security.sasl.util.SecurityIdentitySaslServerFactory$1@50456343->org.wildfly.security.sasl.util.AuthenticationTimeoutSaslServerFactory$DelegatingTimeoutSaslServer@63d1e497->org.wildfly.security.sasl.util.AuthenticationCompleteCallbackSaslServerFactory$1@28b7c921->org.wildfly.security.sasl.digest.DigestSaslServer@52c9104d] for mechanism [DIGEST-MD5]
2018-02-28 13:01:05,286 TRACE [org.wildfly.security] (default task-108) Handling RealmCallback: selected = [ApplicationRealm]
2018-02-28 13:01:05,286 TRACE [org.wildfly.security] (default task-108) Handling NameCallback: authenticationName = aeinstein
2018-02-28 13:01:05,286 TRACE [org.wildfly.security] (default task-108) Principal assigning: [aeinstein], pre-realm rewritten: [aeinstein], realm name: [ApplicationRealm], post-realm rewritten: [aeinstein], realm rewritten: [aeinstein]
2018-02-28 13:01:05,286 TRACE [org.wildfly.security] (default task-108) Executing principalQuery select PASSWORD, 'guest' from PARAGON2_USER where USER_NAME = ? with value aeinstein
2018-02-28 13:01:05,287 TRACE [org.wildfly.security] (default task-108) Handling CredentialCallback: failed to obtain credential
2018-02-28 13:01:05,288 TRACE [org.wildfly.security] (default task-108) Handling RealmCallback: selected = [ApplicationRealm]
2018-02-28 13:01:05,288 TRACE [org.wildfly.security] (default task-108) Handling NameCallback: authenticationName = aeinstein
2018-02-28 13:01:05,288 TRACE [org.wildfly.security] (default task-108) Executing principalQuery select PASSWORD, 'guest' from PARAGON2_USER where USER_NAME = ? with value aeinstein
2018-02-28 13:01:05,288 TRACE [org.wildfly.security] (default task-108) Handling CredentialCallback: obtained credential: org.wildfly.security.credential.PasswordCredential@a30e3c5
2018-02-28 13:01:05,289 TRACE [org.wildfly.security] (default task-108) Executing principalQuery select PASSWORD, 'guest' from PARAGON2_USER where USER_NAME = ? with value aeinstein
2018-02-28 13:01:05,289 TRACE [org.wildfly.security] (default task-108) Executing principalQuery select PASSWORD, 'guest' from PARAGON2_USER where USER_NAME = ? with value aeinstein
2018-02-28 13:01:05,290 TRACE [org.wildfly.security] (default task-108) Role mapping: principal [aeinstein] -> decoded roles [] -> realm mapped roles [] -> domain mapped roles []
2018-02-28 13:01:05,290 TRACE [org.wildfly.security] (default task-108) Authorizing principal aeinstein.
2018-02-28 13:01:05,290 TRACE [org.wildfly.security] (default task-108) Authorizing against the following attributes: [Roles] => [guest]
2018-02-28 13:01:05,290 TRACE [org.wildfly.security] (default task-108) Permission mapping: identity [aeinstein] with roles [] implies ("org.wildfly.security.auth.permission.LoginPermission" "") = true
2018-02-28 13:01:05,290 TRACE [org.wildfly.security] (default task-108) Authorization succeed
2018-02-28 13:01:05,290 TRACE [org.wildfly.security] (default task-108) RunAs authorization succeed - the same identity
2018-02-28 13:01:05,290 TRACE [org.wildfly.security] (default task-108) Handling AuthorizeCallback: authenticationID = aeinstein authorizationID = aeinstein authorized = true
2018-02-28 13:01:05,290 TRACE [org.wildfly.security] (default task-108) Handling AuthenticationCompleteCallback: succeed
2018-02-28 13:01:05,291 TRACE [org.wildfly.security] (default task-108) Handling SecurityIdentityCallback: identity = SecurityIdentity{principal=aeinstein, securityDomain=org.wildfly.security.auth.server.SecurityDomain@1d6152a7, authorizationIdentity=EMPTY, realmInfo=RealmInfo{name='ApplicationRealm', securityRealm=org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm@4f0b78f5}, creationTime=2018-02-28T18:01:05.290Z}
For this exercise I relied upon https://docs.jboss.org/author/display/WFLY/Migrate+Legacy+Security+to+Elytron+Security#MigrateLegacySecuritytoElytronSecurity-ApplicationClientMigration