I've noticed some institutions have a multi-step MFA, for example the first MFA question will be a "token style" request for a phone number, which after submitting, the user gets a text and needs to respond with a token. How does one detect this situation and submit the final step to Yodlee?
Ok this is what Yodlee calls a "Multi level" MFA. You can use DagMultilevel to test this. When checking for an MFA request, this must be in a loop, such that you keep checking after each MFA response to see if "isMessageAvailable" is true.
Along with "isMessageAvailable" you should be checking the error code too, if error code is not null then there is no more MFA present.
If error code is 0 then the request was successful or else it failed with an error.
You can check for those error codes in this page https://developer.yodlee.com/FAQs/Error_Codes
Related
I have some code that uses the Generate SAML Assertion API with users that have MFA (OneLogin Protect) enabled.
Send the Generate SAML Assertion Request, receive a response that Factor Verification is required.
Send the Factor Verify request with app_id, device_id, state_token and do_not_notify=false. This all works well. I receive the notification on my phone.
The code keeps sending the Factor Verify request every 15 seconds (with do_not_notify=true) and waits for the response to contain a data attribute (which is the SAML assertion).
When clicking "Accept" on the phone, the next response will contain the data and everything is well.
But clicking "Deny" on my phone does nothing. All API call contain the message "Authentication pending on OL Protect" (same if not clicking anything) for ~120 seconds and then I received a 400 with "State token is invalid or expired", which is to be expected
If I reduce the time for the requests from 15 to 5 seconds, some sort of flooding protection seems to kick in (I only see a "EOF" without a response after 5-6 API calls).
Is there a way besides timing out to determine that someone clicked "Deny" on OneLogin Protect? This feels like a bug; as soon as someone clicks "Deny", the next API call should indicate that (other IdPs work that way)
I faced same issue with OneLogin Protect. As you have correctly mentioned that the API does nothing after we click on Deny.
To resolve this what I did was, adding some wait say 30 seconds and if even after that it is 401 in the response then I would cancel the request and redirect user to same page he came from.
You can also ask this to OneLogin support here. They are very good and response quickly.
Let me know if it helps.
I'm setting up an authentication where MFA is not optional, which means from the very first login attempt after registration, the user will be asked to set up MFA (in this case I will be using Time Based One Time Passcode, or TOPT). For this, I can see that following steps would be reasonable:
1)Get user information via the login form - Auth.signUp()
2)Determine from the user data retrieved in step 1) whether TOPT-based MFA is set for the user already. If not, go to step 3) or else step 4)
3)If TOPT is not set, redirect to a form where a QRCode will be generated in order to set up this MFA feature. After verifying the code, log the user in.
4)If TOPT is set, ask for the passcode. After verifying, log the user in.
My dilemma: It seems I cannot get the information in Step 2), i.e, whether TOPT-based MFA is set for the user already without the user already being authenticated. The flag challengeName retrieved in the payload via Auth.signUp() in step 1) only gives me info on whether MFA is enabled or not ('MFA_SETUP'), and not whether TOTP-based MFA has been set up already. For that, the method Auth.getPreferredMFA() is what would do the trick, but it only works if the user object being passed to it represents an authenticated (or already logged in) user. Is there a way to determine if TOTP MFA is set up for a user trying to log in (but not logged in yet)?
Also, any other solutions to tackle this problem would be welcome. There must be somebody out there who has run into the same scenario I have, where MFA is mandatory from the first log in itself.
I am facing the same issue. If the MFA is required, I open up a modal to get QR code displayed and setup the mfa for the user.
code: "NotAuthorizedException"
message: "Invalid session for the user."
name: "NotAuthorizedException"
But getting this error because the user hasn't logged in and created any access token yet.
My idea of solving this is actually logging in the user but making their permissions to not go beyond the SetupMFA screen so they only gain some permissions when they have completed the setup.
Have you made any progress yourself? I'd like to hear any solutions.
Re: Yodlee site-based API
a) I know that when adding an MFA account you are supposed to trigger /jsonsdk/Refresh/startSiteRefresh. But if an account is already added and already active, and I want to trigger a manual refresh to get new data, is /jsonsdk/Refresh/startSiteRefresh the correct API to use?
b) When I do use /jsonsdk/Refresh/startSiteRefresh for a manual refresh, I do not want to trigger the whole MFA flow, I simply want to pull new data if possible. So which refreshMode do I specify "MFA" or "NORMAL"?
I ask this, because I used "MFA" mode and it failed with a 522 (timeout) error due to a new security question. But when Yodlee runs the nightly refresh, the same condition will result in a 506 or 518; not a 522. Maybe I am supposed to specify "NORMAL" even for "MFA" accounts for a manual refresh?
You need not pass the refresh mode in the startSiteRefresh API. When you call this API for a siteAccountID the response will tell you if the MFA is required or not. Below fields can be used from the response.
"siteRefreshMode":{
"refreshModeId":1,
"refreshMode":"MFA"
}
Depending on the refreshMode you can follow the MFA flow or Normal flow.
When you trigger this API you will have to flow the complete flow to get the latest data or else the refresh will fail and data will not be updated.
Refer - startSiteRefresh for the API and Refresh Flow for refreshing an account.
I ask this, because I used "MFA" mode and it failed with a 522 (timeout) error due to a new security question. But when Yodlee runs the nightly refresh, the same condition will result in a 506 or 518; not a 522
This is because in case of manual refresh you as a user is not answering the question asked at the end site and hence our server identifies it as no response from the user and hence 522 error code. When it's automatic refresh from Yodlee's end and a new question is encountered the error code is 518.
I need your help regarding MFA flow. Could you tell me please if there is a list of institutions, that use MFA, or if it is possible to get it?
I have found site, that looks like it had MFA, at least it has such data within response (siteSearchString)
"mfaType":{"typeId":4,"typeName":"SECURITY_QUESTION"},"mfaCoverage":"FMPA"
But when I'm getting site login form with this siteID, I'm getting simple login form with
"isMFA": false
When I try to addSiteAccount using this siteId, I'm getting this error:
{
"errorOccurred": "true",
"exceptionType": "com.yodlee.core.IllegalArgumentValueException",
"referenceCode": "_23e71a23-4298-4d86-9271-be9ada8892b0",
"message": "Multiple exceptions encapsulated within: invoke getWrappedExceptions for details"
}
Looks like, that this call requires real credentials for this institution. Am I right? If so, is there any test banks or other financial institution, that use MFA? So we can use them in development mode and not to interact with real ones?
I have found useful generator. So question with test accounts is solved.
Please correct me if I miss something in MFA flow.
Thanks!
The isMFA: false value present in the login form does not make a site MFA.
"mfaType":{"typeId":4,"typeName":"SECURITY_QUESTION"},"mfaCoverage":"FMPA" this value represents if a site is MFA or not.
The exception which you are getting is coming because the login form parameters are not passed correctly in the addSiteAccount API.
You should use getSiteLoginForm API to get the login form for a site and then construct the request of addSiteAccount
Also I would suggest you to go through the API flow to understand the sequence of API to be used correctly.
I would like to differentiate between two scenarios: addSiteAccount API with incorrect credentials and addSiteAccount API with right set of credentials. What I am noticing is that both cases return a siteAccountId with RefreshStatus=Triggered. But when I invoke the same API again or any other API then I get a Login error message.
How can I distinguish between the two cases in a single execution of addSiteAccount ?
So that I could pass the error to end users about incorrect credentials. Thanks.
addSiteAccount1 is the API which will create a siteaccountID i.e. an identifier for that particular account linked.
It will not return any error until you are trying to add same credentials i.e. in that case it will check if you already have added those credentials and will return the response for those credentials.
For understanding how it works:
After calling addSiteAccount1 a siteAccountId willbe created and a refresh would be initiated for that. This will go ahead and validate the credentials passed with the Bank web site and will return the response(success or failure depending upon the credentials passed).
For checking status you need to call getSiteRefreshInfo in loop, I am mentioning the flow for your reference.
(Applicable only for NON- MFA sites)
CobLogin
Register3
Login
AddSiteAccount1 – (this will trigger a refresh request,no need to call startSiteRefresh)
Check for siteRefreshStatus field’s value returned from #4 and if it says “REFRESH_TRIGGERED” , then you can go to #6
Call getSiteRefreshInfo in loop till you get SiteRefreshStatus as either of the following status is received
PARTIAL_COMPLETE– This means that the account level data has been aggregated
REFRESH_COMPLETED– The refresh has been completed.
LOGIN_FAILURE– Login credentials provided was wrong.
REFRESH_CANCELLED– Refresh cancelled by User.
REFRESH_TIMED_OUT– Refresh is taking more time.
7 From #6 you also get a “code” and if the code is 402 then that means credentials were wrong and if it's 0(zero) that means the credentials were correct and the gathering of data was successful. Then you can go to #8 and grab transactions.
Also to know more about error_code see ErrorCode document.
8 ExecuteUserSearchRequest or call any other API depending upon your implementation.