Elytron + JDBCRealm + SHA-256 cannot connect to EJB
rdasilvacuriel Mar 9, 2019 10:18 AMHi, I'm trying to upgrade a personal system from JBossEAP6.4 to Wildfly 15. In EAP6.4 I could connect remotely to my secured EJB's after authenticating via client code. With Wildfly 15 I have the server set up correctly because I can connect to the secured EJB if I store the plain password in the database, and if I use DIGEST-MD5 in my client to connect, also using the clear password. But when I change to SHA-256 in the 'standalone.xml' as follows:
<mechanism-configuration>
<!-- for plain password
<mechanism mechanism-name="DIGEST-MD5">
-->
<mechanism mechanism-name="DIGEST-SHA-256">
<mechanism-realm realm-name="jdbcRealm"/>
</mechanism>
</mechanism-configuration>
I cannot connect using this configuration:
final AuthenticationConfiguration config = AuthenticationConfiguration
.empty()
.useRealm("jdbcRealm")
// .setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("DIGEST-MD5"))
.setSaslMechanismSelector(SaslMechanismSelector.NONE.addMechanism("DIGEST-SHA-256"))
.useName("raoul")
.usePassword("password")
.useProviders(() -> new Provider[]{wildFlyElytronProvider})
In my database I used to store a Base-64 encoded SHA-256 string for "password", namely "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8". I also tried "XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=" and "XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg", but each time I get refused if I try to connect with DIGEST-SHA-256.
16:03:21,305 TRACE [org.wildfly.security] (default I/O-3) Handling MechanismInformationCallback type='SASL' name='DIGEST-SHA-256' host-name='localhost' protocol='remote'
16:03:21,307 TRACE [org.wildfly.security] (default I/O-3) Handling MechanismInformationCallback type='SASL' name='DIGEST-SHA-256' host-name='localhost' protocol='remote'
16:03:21,308 TRACE [org.wildfly.security] (default I/O-3) Handling AvailableRealmsCallback: realms = [jdbcRealm]
16:03:21,358 TRACE [org.wildfly.security] (default I/O-3) Creating SaslServer [org.wildfly.security.sasl.digest.DigestSaslServer@7fef79f2] for mechanism [DIGEST-SHA-256] and protocol [remote]
16:03:21,361 TRACE [org.wildfly.security] (default I/O-3) Created SaslServer [org.wildfly.security.sasl.util.SecurityIdentitySaslServerFactory$1@6d8b87c0->org.wildfly.security.sasl.util.AuthenticationTimeoutSaslServerFactory$DelegatingTimeoutSaslServer@4975f757->org.wildfly.security.sasl.util.AuthenticationCompleteCallbackSaslServerFactory$1@38d22e8f->org.wildfly.security.sasl.digest.DigestSaslServer@7fef79f2] for mechanism [DIGEST-SHA-256]
16:03:21,395 TRACE [org.wildfly.security] (default task-1) Handling RealmCallback: selected = [jdbcRealm]
16:03:21,396 TRACE [org.wildfly.security] (default task-1) Handling NameCallback: authenticationName = raoul
16:03:21,396 TRACE [org.wildfly.security] (default task-1) Principal assigning: [raoul], pre-realm rewritten: [raoul], realm name: [jdbcRealm], post-realm rewritten: [raoul], realm rewritten: [raoul]
16:03:21,400 TRACE [org.wildfly.security] (default task-1) Executing principalQuery SELECT password FROM wrn.user WHERE name = ? with value raoul
16:03:21,430 TRACE [org.wildfly.security] (default task-1) Key Mapper: Password credential created using algorithm column value [simple-digest-sha-256]
16:03:21,431 TRACE [org.wildfly.security] (default task-1) Executing principalQuery SELECT r.name FROM wrn.role r JOIN wrn.User_Roles ur ON ur.role_id=r.id JOIN wrn.user u ON u.id = ur.user_id WHERE u.name=? with value raoul
16:03:21,433 TRACE [org.wildfly.security] (default task-1) Handling CredentialCallback: failed to obtain credential
16:03:21,433 TRACE [org.wildfly.security] (default task-1) Handling RealmCallback: selected = [jdbcRealm]
16:03:21,433 TRACE [org.wildfly.security] (default task-1) Handling NameCallback: authenticationName = raoul
16:03:21,433 TRACE [org.wildfly.security] (default task-1) Handling CredentialCallback: failed to obtain credential
16:03:21,433 TRACE [org.wildfly.security] (default task-1) Handling RealmCallback: selected = [jdbcRealm]
16:03:21,433 TRACE [org.wildfly.security] (default task-1) Handling NameCallback: authenticationName = raoul
16:03:21,434 TRACE [org.wildfly.security] (default task-1) Handling PasswordCallback: failed to obtain PasswordCredential
16:03:21,434 TRACE [org.wildfly.security] (default task-1) Handling AuthenticationCompleteCallback: fail
The jdbcRealm is configured as follows:
<jdbc-realm name="jdbcRealm">
<principal-query sql="SELECT password FROM wrn.user WHERE name = ?" data-source="MySQLDS">
<!-- for plain password
<clear-password-mapper password-index="1"/>
-->
<simple-digest-mapper algorithm="simple-digest-sha-256" password-index="1"/>
</principal-query>
<principal-query sql="SELECT r.name FROM wrn.role r JOIN wrn.User_Roles ur ON ur.role_id=r.id JOIN wrn.user u ON u.id = ur.user_id WHERE u.name=?" data-source="MySQLDS">
<attribute-mapping>
<attribute to="roles" index="1"/>
</attribute-mapping>
</principal-query>
</jdbc-realm>
In "plain password" mode I can connect to the secured EJB successfully, see logging below, so I assume that my EJB and "standalone.xml" configuration is fine. So it must have to do with the SHA-256 configuration, encoding, how I store the password in the database, or how I send the password (encoded, hashed, or whatever) in the client code.
16:08:23,311 TRACE [org.wildfly.security] (default I/O-2) Handling MechanismInformationCallback type='SASL' name='DIGEST-MD5' host-name='localhost' protocol='remote'
16:08:23,312 TRACE [org.wildfly.security] (default I/O-2) Handling MechanismInformationCallback type='SASL' name='DIGEST-MD5' host-name='localhost' protocol='remote'
16:08:23,313 TRACE [org.wildfly.security] (default I/O-2) Handling AvailableRealmsCallback: realms = [jdbcRealm]
16:08:23,369 TRACE [org.wildfly.security] (default I/O-2) Creating SaslServer [org.wildfly.security.sasl.digest.DigestSaslServer@2e544fac] for mechanism [DIGEST-MD5] and protocol [remote]
16:08:23,372 TRACE [org.wildfly.security] (default I/O-2) Created SaslServer [org.wildfly.security.sasl.util.SecurityIdentitySaslServerFactory$1@762cde8b->org.wildfly.security.sasl.util.AuthenticationTimeoutSaslServerFactory$DelegatingTimeoutSaslServer@1d6683e4->org.wildfly.security.sasl.util.AuthenticationCompleteCallbackSaslServerFactory$1@59c6de3->org.wildfly.security.sasl.digest.DigestSaslServer@2e544fac] for mechanism [DIGEST-MD5]
16:08:23,415 TRACE [org.wildfly.security] (default task-1) Handling RealmCallback: selected = [jdbcRealm]
16:08:23,416 TRACE [org.wildfly.security] (default task-1) Handling NameCallback: authenticationName = raoul
16:08:23,417 TRACE [org.wildfly.security] (default task-1) Principal assigning: [raoul], pre-realm rewritten: [raoul], realm name: [jdbcRealm], post-realm rewritten: [raoul], realm rewritten: [raoul]
16:08:23,421 TRACE [org.wildfly.security] (default task-1) Executing principalQuery SELECT password FROM wrn.user WHERE name = ? with value raoul
16:08:23,478 TRACE [org.wildfly.security] (default task-1) Key Mapper: Password credential created using algorithm column value [clear]
16:08:23,480 TRACE [org.wildfly.security] (default task-1) Executing principalQuery SELECT r.name FROM wrn.role r JOIN wrn.User_Roles ur ON ur.role_id=r.id JOIN wrn.user u ON u.id = ur.user_id WHERE u.name=? with value raoul
16:08:23,482 TRACE [org.wildfly.security] (default task-1) Handling CredentialCallback: failed to obtain credential
16:08:23,482 TRACE [org.wildfly.security] (default task-1) Handling RealmCallback: selected = [jdbcRealm]
16:08:23,482 TRACE [org.wildfly.security] (default task-1) Handling NameCallback: authenticationName = raoul
16:08:23,482 TRACE [org.wildfly.security] (default task-1) Handling CredentialCallback: obtained credential: org.wildfly.security.credential.PasswordCredential@dcce299c
16:08:23,487 TRACE [org.wildfly.security] (default task-1) Role mapping: principal [raoul] -> decoded roles [Administrator] -> realm mapped roles [Administrator] -> domain mapped roles [Administrator]
16:08:23,487 TRACE [org.wildfly.security] (default task-1) Authorizing principal raoul.
16:08:23,488 TRACE [org.wildfly.security] (default task-1) Authorizing against the following attributes: [roles] => [Administrator]
16:08:23,490 TRACE [org.wildfly.security] (default task-1) Permission mapping: identity [raoul] with roles [Administrator] implies ("org.wildfly.security.auth.permission.LoginPermission" "") = true
16:08:23,490 TRACE [org.wildfly.security] (default task-1) Authorization succeed
16:08:23,492 TRACE [org.wildfly.security] (default task-1) RunAs authorization succeed - the same identity
16:08:23,492 TRACE [org.wildfly.security] (default task-1) Handling AuthorizeCallback: authenticationID = raoul authorizationID = raoul authorized = true
16:08:23,493 TRACE [org.wildfly.security] (default task-1) Handling AuthenticationCompleteCallback: succeed
16:08:23,493 TRACE [org.wildfly.security] (default task-1) Handling SecurityIdentityCallback: identity = SecurityIdentity{principal=raoul, securityDomain=org.wildfly.security.auth.server.SecurityDomain@15c430d0, authorizationIdentity=EMPTY, realmInfo=RealmInfo{name='jdbcRealm', securityRealm=org.wildfly.security.auth.realm.jdbc.JdbcSecurityRealm@251985a3}, creationTime=2019-03-09T15:08:23.486Z}
16:08:23,759 TRACE [org.wildfly.security] (default task-2) Role mapping: principal [raoul] -> decoded roles [Administrator] -> realm mapped roles [Administrator] -> domain mapped roles [Administrator]
If anyone has any idea how to get this working I would be extremely grateful. I have tried everything, storing different things in the DB, sending hash, hex-encoded passwords, but nothing seems to work. I've also tried different CallbackHandlers but I've wasted a huge number of hours without getting anywhere. Many thanks for any ideas!