AEM Forms Backend Developer Professional study materials
AEM Forms Backend Developer Professional study resources

Adaptive Form submission fails authorization after SSO migration

AEM Forms Backend Developer Professional · Put your knowledge to work in context.

All case studies

Adaptive Form submission fails authorization after SSO migration

An enterprise migrates AEM Forms from local LDAP login to SAML SSO via an IdP. Adaptive Forms with a submit action to a custom servlet (/bin/acme/forms/submit) start returning HTTP 403 for most users after migration. The servlet is registered with @SlingServlet(paths="/bin/acme/forms/submit", methods="POST") and checks request.getUserPrincipal(). Pre-migration, submissions succeeded. Post-migration, a few admin users succeed; regular users get 403. The AF uses guideSubmitAction with a csrf token. The Dispatcher allows POST to /bin/*. SAML assertion maps users to the forms-users group. The servlet's service user has jcr:read on /content/forms but no ACL on the data path /content/acme/customers.

1. Explain the 403 and why admins succeed, then give the fix.

Read the worked answer

The 403 is an authorization failure, not authentication: SSO authenticates the user, but the custom servlet performs work as a service user that lacks ACLs on /content/acme/customers. Admins succeed because they have broad read permissions that the service user does not.

Additional factors to check:

  • The servlet checks request.getUserPrincipal(); under SAML the principal exists but the servlet may then read data as the request user or as a service user. If it reads as the request user, forms-users must have read on the data path; if as a service user, that user needs the ACL.
  • CSRF: the AF must send a valid CSRF token; a missing/invalid token yields 403 too. Verify the token is fetched after SSO and included in the POST.

Fix: grant the appropriate principal (service user or forms-users) least-privilege jcr:read on /content/acme/customers via a rep:policy, and ensure the CSRF token flow works post-SSO. Do not broaden admin-like access.

2. How would you distinguish CSRF 403 from ACL 403 in production, and what hardening would you add?

Read the worked answer

Distinguish by response and logs: AEM's CSRF filter returns 403 with a CSRF-specific message/log entry (e.g., 'CSRF token' / 'Invalid CSRF token') before the servlet runs; ACL denials log an AccessDeniedException from the repository and the servlet's own logging executes. Add request-id logging at the servlet entry: if the log line appears, the 403 came from ACL inside the servlet; if not, it was the CSRF filter.

Hardening:

  • Enforce CSRF on the custom servlet (AEM CSRF filter covers POST; ensure the AF includes the token).
  • Use a dedicated service user with least privilege and map it with ServiceUserMapped; avoid running as admin.
  • Validate and sanitize submitted data; restrict the servlet path in Dispatcher to the exact path and method.
  • Add audit logging of principal, path, and outcome; alert on 403 spikes.
  • Test the SSO + CSRF + ACL matrix in staging with a non-admin forms-users account.