| Description | In environments that integrate two-factor authentication it is important to understand the message flow. If troubleshooting is required, it is important to understand what messages may be problematic or missing, in order to troubleshoot at the correct node that introduces the failure. This article describes the message flow of the various nodes used in 2FA-setups with three examples. Note that these are examples and not an exhaustive list. The flow may vary on the deployment and introduce other components whose presence needs to be understood. |
| Scope | RADIUS clients like FortiGate, RADIUS servers like FortiAuthenticator |
| Solution |
The minimum setup for 2FA would include a RADIUS server like FortiAuthenticator, set up to ask for the second factor in form of a One-Time-Password (OTP) and a RADIUS client asking to authenticate. In such setups, there are several roles that may appear multiple times and even can be shared by a single node.
In this set of roles, the client (a) wouldn't know what role the server (b) actually has or to which user database (c) the user would authenticate to. This flow is entirely sequential. (c) will not know what (a) is and vice versa.
A common setup consists of some client authenticating to FortiGate web UI, a FortiAuthenticator as RADIUS server that also injects 2FA and a domain controller. In other words, the client authenticates to FortiGate, the FortiGate tries to authenticate the user towards the FortiAuthenticator via RADIUS and FortiAuthenticator tries to authenticate the user towards the domain controller via LDAP. The simple authentication flow would then follow this layout:
client (a) <SSH (or HTTPS)> FortiGate (b) <RADIUS> FortiAuthenticator (c) <LDAP> Domain controller (d)
The message flow between those four nodes is sequential. One node speaks to the next and expects a response. (a) speaks to (b) and expects a response. (a) does not interact with (c) or (d). (b) also would not interact with (d). If (b) is waiting for a response from (c), this also means that (a) is waiting for a response from (b). If (c) does not send a response, (b) will not return one to (a) either.
The following flow attempts to visualize this:
Note: The nodes happen to be example products, but the FortiManager can be a FortiGate, or something else like an OpenSSH server. The FortiAuthenticator may also be a different type of server. The steps itself:
So if (d) rejects authentication, but the credentials provided from (a) to (d) (over (b) and (c)) are correct, the reason on the server that creates the unexpected response, must be understood. Troubleshooting (b) or (c) may not lead somewhere unless either node has the capability to change the appearance of credentials (like RADIUS authentication method, username format as an example).
The second example utilizes an additional step, where FortiAuthenticator was inserted in an existing RADIUS communication to inject a 2FA prompt, without touching the existing RADIUS client or RADIUS server.
Client (a) <SSH (or HTTPS)> FortiGate (b) <RADIUS 1> FortiAuthenticator (c) <RADIUS 2> RADIUS server (d) <LDAP> Domain controller (e).
The third example is a bit complex as it reflects a function that FortiAuthenticator authenticate the user towards the LDAP-server (first factor), like in the first example, but will then contact the second RADIUS server that would only query for the second factor.
The following flow diagram visualizes this:
The message flow broken down:
In either case, it helps to understand what message in this flow is not working and up until which point the messages follow that flow. Troubleshoot the node that produces a flow that deviates from the description. |
The Fortinet Security Fabric brings together the concepts of convergence and consolidation to provide comprehensive cybersecurity protection for all users, devices, and applications and across all network edges.
Copyright 2026 Fortinet, Inc. All Rights Reserved.