FailedLoginException with SaltedDatabaseServerLoginModule (PBKDF2)
luckysamba555 Jan 25, 2017 3:54 PMI'm trying to implement SaltedDatabaseServerLoginModule in Wildfly security domain using PBKDF2 for hashing passwords. But constantly getting "FailedLoginException: PBOX00070: Password invalid/Password required". I suspect that something is wrong with hashing passwords, when a password from a database is compared to an entered password in the login-module. Could it be that a password gets hashed twice?
I'm using this method to create a hashed password in my code:
public static String hash(String plainText, String storedPassword) { if (plainText == null) return null; SimplePBKDF2 crypto = new SimplePBKDF2(); PBKDF2Parameters params = crypto.getParameters(); params.setHashCharset("UTF-8"); params.setHashAlgorithm("HmacSHA1"); params.setIterationCount(1000); if (storedPassword != null) { new PBKDF2HexFormatter().fromString(params, storedPassword); } return crypto.deriveKeyFormatted(plainText); }
standalone.xml
<security-domain name="secureDomain"> <authentication> <login-module code="de.rtner.security.auth.spi.SaltedDatabaseServerLoginModule" flag="required" module="de.rtner.PBKDF2"> <module-option name="dsJndiName" value="java:/PostgresDS"/> <module-option name="principalsQuery" value="SELECT password FROM users WHERE login=?"/> <module-option name="rolesQuery" value="SELECT R.ROLE, 'Roles' FROM ROLES R INNER JOIN USER_ROLES UR ON UR.ROLE_ID = R.ID INNER JOIN USERS U ON U.ID = UR.USER_ID WHERE U.LOGIN=?"/> <module-option name="hmacAlgorithm" value="HMacSHA1"/> <module-option name="formatter" value="de.rtner.security.auth.spi.PBKDF2HexFormatter"/> <module-option name="engine" value="de.rtner.security.auth.spi.PBKDF2Engine"/> <module-option name="engine-parameters" value="de.rtner.security.auth.spi.PBKDF2Parameters"/> </login-module> </authentication> </security-domain>
web.xml
<login-config> <auth-method>BASIC</auth-method> <realm-name>secureDomain</realm-name> </login-config> <security-constraint> <display-name>Admin Pages</display-name> <web-resource-collection> <web-resource-name>Admin Views</web-resource-name> <description>application security constraints</description> <url-pattern>/admin/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> <http-method>DELETE</http-method> </web-resource-collection> <auth-constraint> <role-name>ADMIN</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <security-role> <role-name>ADMIN</role-name> </security-role>
jboss-web.xml
<?xml version="1.0" encoding="UTF-8"?> <jboss-web> <security-domain>secureDomain</security-domain> </jboss-web>
server.log
2017-01-26 00:05:06,104 TRACE [org.jboss.security] (default task-1) PBOX00354: Setting security roles ThreadLocal: null 2017-01-26 00:05:06,536 TRACE [org.jboss.security] (default task-3) PBOX00354: Setting security roles ThreadLocal: null 2017-01-26 00:05:08,003 TRACE [org.jboss.security] (default task-4) PBOX00354: Setting security roles ThreadLocal: null 2017-01-26 00:05:15,012 TRACE [org.jboss.security] (default task-5) PBOX00200: Begin isValid, principal: org.wildfly.extension.undertow.security.AccountImpl$AccountPrincipal@586034f, cache entry: null 2017-01-26 00:05:15,032 TRACE [org.jboss.security] (default task-5) PBOX00209: defaultLogin, principal: org.wildfly.extension.undertow.security.AccountImpl$AccountPrincipal@586034f 2017-01-26 00:05:15,034 TRACE [org.jboss.security] (default task-5) PBOX00221: Begin getAppConfigurationEntry(secureDomain), size: 6 2017-01-26 00:05:15,041 TRACE [org.jboss.security] (default task-5) PBOX00224: End getAppConfigurationEntry(secureDomain), AuthInfo: AppConfigurationEntry[]: [0] LoginModule Class: de.rtner.security.auth.spi.SaltedDatabaseServerLoginModule ControlFlag: LoginModuleControlFlag: required Options: name=dsJndiName, value=java:/PostgresDS name=formatter, value=de.rtner.security.auth.spi.PBKDF2HexFormatter name=principalsQuery, value=SELECT password FROM users WHERE login=? name=rolesQuery, value=SELECT R.ROLE, 'Roles' FROM ROLES R INNER JOIN USER_ROLES UR ON UR.ROLE_ID = R.ID INNER JOIN USERS U ON U.ID = UR.USER_ID WHERE U.LOGIN=? name=engine, value=de.rtner.security.auth.spi.PBKDF2Engine name=hmacAlgorithm, value=HMacSHA1 name=engine-parameters, value=de.rtner.security.auth.spi.PBKDF2Parameters 2017-01-26 00:05:15,051 TRACE [org.jboss.security] (default task-5) PBOX00236: Begin initialize method 2017-01-26 00:05:15,051 TRACE [org.jboss.security] (default task-5) PBOX00262: Module options [dsJndiName: java:/PostgresDS, principalsQuery: SELECT password FROM users WHERE login=?, rolesQuery: SELECT R.ROLE, 'Roles' FROM ROLES R INNER JOIN USER_ROLES UR ON UR.ROLE_ID = R.ID INNER JOIN USERS U ON U.ID = UR.USER_ID WHERE U.LOGIN=?, suspendResume: true] 2017-01-26 00:05:15,054 TRACE [org.jboss.security] (default task-5) PBOX00240: Begin login method 2017-01-26 00:05:15,086 TRACE [org.jboss.security] (default task-5) PBOX00263: Executing query SELECT password FROM users WHERE login=? with username admin 2017-01-26 00:05:15,524 DEBUG [org.jboss.security] (default task-5) PBOX00283: Bad password for username admin 2017-01-26 00:05:15,525 TRACE [org.jboss.security] (default task-5) PBOX00244: Begin abort method, overall result: false 2017-01-26 00:05:15,526 DEBUG [org.jboss.security] (default task-5) PBOX00206: Login failure: javax.security.auth.login.FailedLoginException: PBOX00070: Password invalid/Password required at org.jboss.security.auth.spi.UsernamePasswordLoginModule.login(UsernamePasswordLoginModule.java:286) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755) at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195) at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682) at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680) at javax.security.auth.login.LoginContext.login(LoginContext.java:587) at org.jboss.security.authentication.JBossCachedAuthenticationManager.defaultLogin(JBossCachedAuthenticationManager.java:406) at org.jboss.security.authentication.JBossCachedAuthenticationManager.proceedWithJaasLogin(JBossCachedAuthenticationManager.java:345) at org.jboss.security.authentication.JBossCachedAuthenticationManager.authenticate(JBossCachedAuthenticationManager.java:323) at org.jboss.security.authentication.JBossCachedAuthenticationManager.isValid(JBossCachedAuthenticationManager.java:146) at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verifyCredential(JAASIdentityManagerImpl.java:123) at org.wildfly.extension.undertow.security.JAASIdentityManagerImpl.verify(JAASIdentityManagerImpl.java:94) at io.undertow.security.impl.BasicAuthenticationMechanism.authenticate(BasicAuthenticationMechanism.java:167) at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:245) at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.transition(SecurityContextImpl.java:263) at io.undertow.security.impl.SecurityContextImpl$AuthAttempter.access$100(SecurityContextImpl.java:231) at io.undertow.security.impl.SecurityContextImpl.attemptAuthentication(SecurityContextImpl.java:125) at io.undertow.security.impl.SecurityContextImpl.authTransition(SecurityContextImpl.java:99) at io.undertow.security.impl.SecurityContextImpl.authenticate(SecurityContextImpl.java:92) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:55) at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:33) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)
users table
CREATE TABLE users ( id bigint NOT NULL, name text, address text, login text, password character varying(255), email text, payment text, PRIMARY KEY (id) );