Multi-Factor Authentication (MFA)

Note: This page is about MFA support within the Finicity API. For MFA support in the Financial Data API Facade, see Multi-Factor Authentication (MFA) in the Facade.

The term Multi-Factor Authentication (MFA) describes various styles of authentication challenges provided by financial institutions, such as text questions, image matching, “captcha” images, etc.

All services that access an institution directly provide handling for MFA challenges that may be presented by the institution. These include services associated with Customer Account Discovery, Activation, and Refresh, Cash Flow Verification (Historic Transactions), and Account Ownership Verification (PDF Statements).

An MFA challenge is indicated when the service returns HTTP 203 instead of the usual HTTP success codes of 200, 201, or 204.

See Testing Accounts to understand how to validate your handling of the various MFA styles.

MFA Frequency

Many institutions present MFA challenges when an account is accessed from a new machine or browser. When the MFA challenge is answered correctly, the institution will send a cookie or provide some other mechanism to avoid MFA for subsequent connections from the same environment. The cookie is usually valid for some period of time (such as 30 days or 90 days, depending on the institution's policy).

The Finicity platform is typically treated as a new machine, so the institution will require MFA on the first connection from Finicity, during account discovery. When the MFA challenge is answered correctly, the Finicity platform will store any cookie that is provided by the institution, in order to bypass MFA for subsequent calls to refresh that account.

This means that after an account has been activated, most calls through the API will not require additional MFA challenges. However, the client app must allow for the possibility that any of these calls may return HTTP 203 with an MFA challenge, because it will happen again whenever the account's stored MFA bypass expires.

A Finicity testing account that is configured for MFA will always return an MFA challenge from any call that may connect to the institution. This is done to allow validation of every aspect of the client app's MFA handling; this behavior should not be seen as an example of how real-world accounts will perform.

MFA Session Identifier

When a service returns HTTP 203 with an MFA challenge, the HTTP response will include an HTTP header named MFA-Session. The header must be copied directly to the HTTP request that is sent with the answer(s) to the MFA challenge. This sequence allows the platform to continue the aggregation process that was interrupted by the MFA challenge.

The MFA session identifier expires after 120 seconds, and is only valid for one reply to an MFA challenge. There is never a reason to store the MFA session identifier for use in later requests.

If one of the answers sent for an MFA challenge is rejected, your application must start again at the beginning of the sequence to obtain a new MFA session identifier.

If an institution requires a series of MFA challenges, the HTTP response returned for each challenge will contain a new and different MFA session identifier. In each case, your application should copy the MFA-Session header from the response to the new HTTP request to answer that specific MFA challenge.

Handling Encoded Images

MFA styles that use images will return the image data in a standard Base64-encoded format. This format is handled natively by HTML, Javascript, CSS, and other formats.

To view the image in a browser, you can usually just paste the contents of the image element, such as data:image/png;base64,R0l...AOw==, directly into the URL or Address field of your browser.

To display the image in an HTML document, paste the contents of the image element directly into the src attribute of an HTML <img> tag. For example, if the MFA challenge includes this element:

  <image>data:image/png;base64,R0l...AOw==</image>

...the image can be displayed in an HTML document like this:

  <html><body><img src="data:image/png;base64,R0l...AOw=="/></body></html>

For an explanation of Base64 encoding, see this page on the FreeFormatter website. The page gives examples showing how to display Base64 images in Javascript, CSS, and other formats, and includes a utility for experimenting with this encoding style. To view a decoded image using the FreeFormatter utility, do the following:

  1. Paste into the "Option 1" field all of the image data following the string "base64," (In the example above, you would paste the text R0l...AOw== into the field.)
  2. Click the button Decode and Download.

Your browser will store the output as a file on disk, which can be viewed with any image viewer.

MFA Challenges Segment

XML Name Description
mfaChallenges Root element
questions Wrapper for all <question> elements.
question

A single challenge entry (see below for examples).

Note that the mfaChallenges element may include multiple individual question elements. The client app must handle the case where multiple questions are returned in a single MFA challenge response.

answer Added by the partner for calls to the "MFA Answers" services

MFA Styles

You can experiment with the various styles of MFA using testing accounts. There are testing account credentials for each MFA style.

Text based MFA

Testing account credentials: tfa_text :: go

JSON example:

HTTP 203 Response:

{
"questions": [
{
"text": "Enter name of your first pet."
} ]
}

Inside the Subsequent Request:

{
"mfaChallenges": {
"questions": [
{
"text": "Enter name of your first pet.",
"answer": "PET_NAME"
} ]
}
}

XML example:

<mfaChallenges>
  <questions>
    <question>
      <text>Enter your first pet's name:</text>
      <answer>PET_NAME (MFA Answers only)</answer>
    </question>
  </questions>
</mfaChallenges>

Image Captcha MFA

Testing account credentials: tfa_image :: go

JSON Example:

HTTP 203 Response:

{
"questions": [
{
"text": "Enter image text",
"image": "data:image/png;base64,/9j...9k="
} ]
}

Inside the Subsequent Request:

{
"mfaChallenges": {
"questions": [
{
"text": "Enter image text",
"answer": "IMAGE_TEXT"
} ]
}
}

XML Example:

HTTP 203 Response:

<mfaChallenges>
  <questions>
    <question>
      <text>Enter image text</text>
      <image>data:image/png;base64,/9j...9k=</image>
    </question>
  </questions>
</mfaChallenges>

Inside the Subsequent Request:

<mfaChallenges>
  <questions>
    <question>
      <text>Enter image text</text>
      <answer>IMAGE_TEXT</answer>
    </question>
  </questions>
</mfaChallenges>

Multiple Text Options MFA

Testing account credentials: tfa_choice :: go

JSON Example:

HTTP 203 Response:

{
"questions": [
{
"text": "Which high school did you attend?",
"choices": [
{
"choice": "Washington",
"value": "Washington"
},
{
"choice": "Jefferson",
"value": "Jefferson"
},
{
"choice": "Wilson",
"value": "Wilson"
},
{
"choice": "Fail",
"value": "fail"
} ]
} ]
}

Inside the Subsequent Request:

{
"mfaChallenges": {
"questions": [
{
"text": "Which high school did you attend?",
"choices": [
{
"choice": "Washington",
"value": "Washington"
},
{
"choice": "Jefferson",
"value": "Jefferson"
},
{
"choice": "Wilson",
"value": "Wilson"
},
{
"choice": "Fail",
"value": "fail"
} ],
"answer": "Washington"
} ]
}
}

XML Example:

<mfaChallenges>
  <questions>
    <question>
      <text>Which high school did you attend?</text>
      <choice value="Washington">Washington</choice>
      <choice value="Jefferson">Jefferson</choice>
      <choice value="Wilson">Wilson</choice>
      <answer>Washington (MFA Answers only)</answer>
    </question>
  </questions>
</mfaChallenges>

Image Choice MFA, Style 1

Testing account credentials: demo :: imagechoice  OR  tfa_multi :: go

JSON Example:

HTTP 203 Response:

{
"questions": [
{
"text": "Choose your favorite sport",
"imageChoices": [
{
"imageChoice": "data:image/png;base64,/9j/4...B//2Q==",
"value": "cricket"
},
{
"imageChoice": "data:image/png;base64,/9j/4...Z//Z",
"value": "hockey"
},
{
"imageChoice": "data:image/png;base64,/9j/4...f//Z",
"value": "soccer"
},
{
"imageChoice": "data:image/png;base64,/9j/4...x//9k=",
"value": "f1"
} ]
} ]
}

Inside the Subsequent Request:

{
"mfaChallenges": {
"questions": [
{
"text": "Choose your favorite sport",
"answer": "cricket"
} ]
}
}

XML Example:

HTTP 203 Response:

<mfaChallenges>
  <questions>
    <question>
      <text>Choose your favorite sport</text>
      <imageChoice value="cricket">data:image/png;base64,/9j/4...B//2Q==</imageChoice>
      <imageChoice value="hockey">data:image/png;base64,/9j/4...Z//Z</imageChoice>
      <imageChoice value="soccer">data:image/png;base64,/9j/4...f//Z</imageChoice>
      <imageChoice value="f1">data:image/png;base64,/9j/4...x//9k=</imageChoice>
    </question>
  </questions>
</mfaChallenges>

Inside the Subsequent Request:

<accounts>
<mfaChallenges> <questions> <question> <text>Choose your favorite sport</text> <answer>cricket</answer> </question> </questions> </mfaChallenges>
</accounts>

Image Choice MFA, Style 2

Testing account credentials: demo :: imagechoice2

In this case, there is an extra image element, containing an image that should be displayed, but is not one of the answers that can be selected.

JSON Example:

HTTP 203 Response:

{
"questions": [
{
"text": "Choose your favorite sport",
"imageChoices": [
{
"imageChoice": "data:image/png;base64,R0l...AOw==",
"value": "rb_00"
},
{
"imageChoice": "data:image/png;base64,R0l...AOw==",
"value": "rb_01"
},
{
"imageChoice": "data:image/png;base64,R0l...AA7",
"value": "rb_02"
},
{
"imageChoice": "data:image/png;base64,R0l...ADs=",
"value": "rb_03"
},
{
"imageChoice": "data:image/png;base64,R0l...GBAA7",
"value": "rb_04"
} ],
"image": "data:image/png;base64,R0l...QADs="
} ]
}

Inside the Subsequent Request:

{
"mfaChallenges": {
"questions": [
{
"text": "Choose your favorite sport",
"answer": "rb_03"
} ]
}
}

XML Example:

HTTP 203 Response:

<mfaChallenges>
  <questions>
    <question>
      <text>Choose your favorite sport</text>
      <imageChoice value="rb_00">data:image/png;base64,R0l...AOw==</imageChoice>
      <imageChoice value="rb_01">data:image/png;base64,R0l...AOw==</imageChoice>
      <imageChoice value="rb_02">data:image/png;base64,R0l...AA7</imageChoice>
      <imageChoice value="rb_03">data:image/png;base64,R0l...ADs=</imageChoice>
      <imageChoice value="rb_04">data:image/png;base64,R0l...GBAA7</imageChoice>
      <image>data:image/png;base64,R0l...QADs=</image>
</question> </questions> </mfaChallenges>

Inside the Subsequent Request:

<accounts>
<mfaChallenges> <questions> <question> <text>Choose your favorite sport</text> <answer>rb_03</answer> </question> </questions> </mfaChallenges>
</accounts>
Have more questions? Submit a request

Comments

Powered by Zendesk