Hi Krishna,

Thanks for putting this together. Native MFA is something OFBiz has needed
for a long time, and the staged login (holding back the successful-login
bookkeeping until the second factor passes) looks like the right foundation
to me. I read the document and both PRs, then applied them on current trunk
and tried the flows locally with MFA enabled. Enrollment, the login
challenge, replay rejection of a used code and the isolation of the pending
session all worked well for me.

Here is what I ran into while testing:

* Wrong codes are limited per challenge only. I entered 18 wrong codes
across three password logins and could still log in with a valid code
afterwards; successiveFailedLogins was never touched. I think failed
second-factor attempts need to count towards the account lockout, on both
the web and REST paths.
* An account that is disabled while its login is waiting at the challenge
page gets logged in and re-enabled (enabled=Y, disabledBy cleared) once the
code is submitted. The account state probably needs to be re-checked at
completion.
* With HTTP header login, the challenge is shown but a valid code ends in
"Unable to complete login" (completeUserLoginMfa returns
"Authentication-factor policy changed; restart login"). From the code I
expect the same for the JWT, remote user and certificate paths.
* On REST, a challenge created through /rest/auth/token can be verified
through /rest/auth/{anyGroup}/mfa/{challengeId}/verify, and the token is
issued for that group without the group being validated or its base
permission checked.
* The Basic auth filter still runs the full userLogin service, so
UserLoginHistory is written at step 1, before the second factor.
* Once the re-authentication window has passed, password change and factor
management ask the user to "sign in again", and I could not find a way to
re-verify a code without logging out.

A few design points I would like to discuss:

* Recovery: there are no backup codes, and email password recovery is
blocked for MFA accounts, so a lost phone needs an administrator. That may
be hard on storefront customers.
* Channels: it would help to list every authentication channel in the
proposal (service-level login.username/login.password, REST, JWT SSO,
header and certificate login, external login key) and how each one behaves
when MFA is required.
* Library: dev.samstevens.totp has not had a release since 2020 and brings
in commons-net and zxing javase, while we only use its code and secret
generators. Since zxing core is already a dependency and RFC 6238 is small,
I would lean towards implementing it on javax.crypto and testing against
the RFC vectors, or picking a maintained library.
* Standards: I believe "totp" is not a registered amr value in RFC 8176
("otp" and "mfa" are). It would also be good to confirm the factor model
leaves room for WebAuthn/passkeys later, since TOTP alone is not phishing
resistant.

Some smaller things:

* The document and the code differ in places: the QR code is a PNG rather
than SVG, the acr claim and the totp.window property are not in the code,
and the re-authentication window is 300 seconds.
* A few changes apply even when MFA is disabled: the updatePassword event
replacement, the form macro changes in the common theme, and the external
login key lifetime going from 2 to 15 minutes. I think these are better as
separate tickets so that nothing changes for existing deployments.
* * Most of the new UI text is hardcoded in English, and Working.md at the
repository root would be better placed with the rest of the documentation
rather than at the top level.

Would it be possible to create a Jira ticket and split the work into
smaller PRs (entities and services, web login flow, REST, storefront)? That
would make it much easier to review and test each part. I am happy to add
line-level comments on the PRs and to help test the next iteration.

Thanks again for the effort on this.

Regards,
Mridul Pathak

On Wed, Nov 11, 2026 at 4:55 PM Krishna Uprit <
[email protected]> wrote:

> Hi everyone,
>
> Modern identity security standards (*NIST SP 800-63B, PCI-DSS 4.0*)
> increasingly require *Multi-Factor Authentication (MFA)* for enterprise and
> administrative applications.
>
> - While Apache OFBiz provides solid primary credential handling,
> secondary factor
> verification has historically required custom integration or third-party
> gateways.
>
> Over the past few weeks, I have designed and implemented a native, *RFC
> 6238 Time-Based One-Time Password (TOTP)* architecture for Apache OFBiz.
> The goal is to provide a production-ready, zero-trust MFA capability that
> adheres strictly to core OFBiz idioms without breaking existing
> deployments.
>
> - *Detailed Proposal Document:*
>
> I have compiled a comprehensive architecture proposal covering entity
> models, session state boundaries, controller flows, and REST token
> specifications:
>
> *Document:*
>
> https://docs.google.com/document/d/1Ugqe8Z5vm2Ikkr55o2eDlYbjpvszVbuuEK8P-e-tzYw/edit?usp=sharing
>
> *Architectural Highlights:*
>
> • *Staged Authentication Lifecycle:*
>
> -- Introduces an isolated intermediate stage (*PRIMARY_VERIFIED ➔
> MFA_PENDING ➔ AUTHENTICATION_COMMITTED*).
> -- This guarantees that user sessions, cookies, or successful login
> histories are never committed to the database until the second factor
> is successfully
> verified, preventing pre-MFA state poisoning.
>
> • *Air-Gapped RFC 6238 TOTP:*
>
> -- Compatible with standard authenticators (*Google Authenticator,
> Microsoft Authenticator,* etc.).
> -- QR codes are generated directly *in-memory *as SVG Data URIs—no external
> CDNs or third-party web APIs (like Google Charts) are ever contacted.
>
> • *Double Session Rotation:*
>
> -- HTTP session IDs are regenerated upon primary password entry, and
> regenerated again immediately upon TOTP verification to mitigate session
> fixation.
>
> • *Granular Policy & Interstitials:*
>
> -- Supports self-service enrollment under user profiles as well as
> group-level mandatory enforcement (requireAuthFactor="Y" on SecurityGroup)
> with forced enrollment interstitials.
>
> • *Two-Step REST API Handshake:*
>
> *-- *The /rest component supports an interactive two-step token exchange
> (HTTP
> 202 MFA_REQUIRED challenge returning opaque ID ➔ verification returning JWT
> with RFC 8176 amr: ["pwd", "totp"] and acr: "loa-mfa" claims).
>
> • *Complete UI Support (Backoffice + B2C Storefront):*
>
> *-- *Fully integrated into core backoffice themes, as well as the
> public customer
> storefront (plugins/ecommerce).
>
> • *100% Backward Compatibility:*
>
> -- The feature is globally disabled by default (
> *security.login.authFactor.enable=false*).
> -- Existing service calls, automated integration test suites, and
> password-only workflows continue to operate without any breaking changes.
>
> *Implementation & Verification:*
>
> The code has been verified with comprehensive integration tests
> (UserLoginTests.groovy, LoginEventsTests.java, and
> JWTManagerAssuranceTests.java
> covering challenge lifecycles, replay rejection, forced enrollment, step-up
> password changes, and token claims).
>
> - The implementation is split cleanly across the framework and plugins
> repositories:
>
>   • *Framework Pull Request:*
> https://github.com/apache/ofbiz-framework/pull/2620
>   • *Plugins Pull Request:*
> https://github.com/apache/ofbiz-plugins/pull/523
>
> I would like to invite the community to review the proposal document, look
> through the PR's, and share your valuable thoughts and feedback.
>
> Kind Regards,
> Krishna Uprit
> Application Security Engineer
> *HotWax Systems*
> *Enterprise open source experts*
> cell: +91-7999304341 <+91%2079993%2004341> <+91%2079993%2004341>
> http://www.hotwaxsystems.com
>

Reply via email to