{"record":{"id":"e5acb1205f2b486a","repo":"apereo/cas","slug":"failed-to-authenticate-user","errorCode":null,"errorMessage":"Failed to authenticate user","messagePattern":"Failed to authenticate user","errorType":"exception","errorClass":"FailedLoginException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/StoredProcedureAuthenticationHandler.java","lineNumber":40,"sourceCode":"public class StoredProcedureAuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler<ProcedureJdbcAuthenticationProperties> {\n\n    public StoredProcedureAuthenticationHandler(\n        final ProcedureJdbcAuthenticationProperties properties,\n        final PrincipalFactory principalFactory, final DataSource dataSource) {\n        super(properties, principalFactory, dataSource);\n    }\n\n    @Override\n    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(\n        final UsernamePasswordCredential credential, final String originalPassword) throws Throwable {\n        val username = credential.getUsername();\n        val password = credential.toPassword();\n\n        val jdbcCall = new SimpleJdbcCall(jdbcTemplate).withProcedureName(properties.getProcedureName());\n        val results = jdbcCall.execute(Map.of(\"username\", username, \"password\", password));\n        LOGGER.debug(\"Procedure results are [{}]\", results);\n        if (results.isEmpty() || !BooleanUtils.toBoolean(results.get(\"status\").toString())) {\n            throw new FailedLoginException(\"Failed to authenticate user\");\n        }\n        val principal = principalFactory.createPrincipal(username, CollectionUtils.toMultiValuedMap(results));\n        return createHandlerResult(credential, principal, new ArrayList<>());\n    }\n}\n","sourceCodeStart":22,"sourceCodeEnd":46,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-jdbc-authentication/src/main/java/org/apereo/cas/jdbc/StoredProcedureAuthenticationHandler.java#L22-L46","documentation":"StoredProcedureAuthenticationHandler calls the configured stored procedure with username/password and expects a 'status' output that is truthy. If the result map is empty or status evaluates false, FailedLoginException 'Failed to authenticate user' is thrown.","triggerScenarios":"SimpleJdbcCall.execute returns empty results, or the results map lacks a 'status' key, or status is '0'/'false' after BooleanUtils.toBoolean.","commonSituations":"Procedure returns keys with different case or naming (e.g. STATUS, return_status) so results.get(\"status\") is null; procedure returns no result set on failure; procedure always returns 0 because of internal logic/schema drift.","solutions":["Inspect the debug log 'Procedure results are [...]' and confirm the actual key name; fix the procedure or the extraction to match it.","Update the stored procedure to return status=1 on success.","Verify procedureName matches the actual stored procedure and the user has EXECUTE permission.","Confirm the function call parameters (username, password) match the procedure signature."],"exampleFix":"// before: procedure outputs @status_value\n// after: name the output parameter 'status' in the procedure\nCREATE PROCEDURE auth_user(IN username VARCHAR, IN password VARCHAR, OUT status INT)\nBEGIN SELECT COUNT(*) INTO status FROM users WHERE ...; END;","handlingStrategy":"try-catch","validationCode":"// Verify the procedure exists and is executable\njdbcTemplate.execute(\"CALL auth_user('probe','probe',@status)\");\nInteger status = jdbcTemplate.queryForObject(\"SELECT @status\", Integer.class);","typeGuard":"Object status = results.get(\"status\");\nif (status == null || !BooleanUtils.toBoolean(status.toString())) { throw new FailedLoginException(); }","tryCatchPattern":"try { result = handler.authenticate(credential); }\ncatch (FailedLoginException e) { log.warn(\"Stored procedure auth returned failure: {}\", e.getMessage()); }","preventionTips":["Ensure the procedure names its output parameter exactly 'status'.","Grant EXECUTE permission to the CAS DB user.","Log the full results map during initial integration."],"tags":["jdbc","stored-procedure","authentication"],"backgroundTag":"authentication-failed","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}