-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem: 2-Factor Authentication using IBEAM_TWO_FA_HANDLER=EXTERNAL_REQUEST #185
Comments
Hey @xjcarter! Many thanks for submitting the detailed issue report - and if what GitHub is reporting is true: congrats on your first issue here! 👏 To address a few points here:
Correct, just a 6-digit string should be expected.
It's defined by
The full list of env vars supported by that handler is confusingly defined in the handler itself - as opposed to in the _EXTERNAL_REQUEST_METHOD = os.environ.get('IBEAM_EXTERNAL_REQUEST_METHOD', 'GET')
"""Method to use by the external request 2FA handler."""
_EXTERNAL_REQUEST_URL = os.environ.get('IBEAM_EXTERNAL_REQUEST_URL')
"""URL to use by the external request 2FA handler."""
_EXTERNAL_REQUEST_TIMEOUT = int(os.environ.get('IBEAM_EXTERNAL_REQUEST_TIMEOUT', 300))
"""Timeout for the external 2FA request."""
_EXTERNAL_REQUEST_PARAMS = os.environ.get('IBEAM_EXTERNAL_REQUEST_PARAMS')
"""JSON-formatted URL params to use by the external request 2FA handler."""
_EXTERNAL_REQUEST_DATA = os.environ.get('IBEAM_EXTERNAL_REQUEST_DATA')
"""JSON-formatted POST data to use by the external request 2FA handler."""
_EXTERNAL_REQUEST_HEADERS = os.environ.get('IBEAM_EXTERNAL_REQUEST_HEADERS')
"""JSON-formatted headers to use by the external request 2FA handler."""
Yeah, there are defaults (see the answer above), so you only need to set values that are needed. Now, from the logs you've shared I conclude that IBeam hasn't even reached the 2FA stage. The authentication step does something unexpected. IBeam suggests increasing None of these triggers are present, causing the timeout: trigger, target = wait_and_identify_trigger(
has_text(targets['SUCCESS']),
is_visible(targets['TWO_FA']),
is_visible(targets['TWO_FA_SELECT']),
is_visible(targets['TWO_FA_NOTIFICATION']),
is_visible(targets['ERROR']),
is_clickable(targets['IBKEY_PROMO']),
) This is pretty unusual. The corresponding 2FA targets are: TWO_FA_EL_ID = os.environ.get('IBEAM_TWO_FA_EL_ID', 'ID@@twofactbase')
"""HTML element check for if Gateway will require 2FA code authentication."""
TWO_FA_NOTIFICATION_EL = os.environ.get('IBEAM_TWO_FA_NOTIFICATION_EL', 'CLASS_NAME@@login-step-notification')
"""HTML element check for if Gateway will require 2FA notification authentication."""
TWO_FA_INPUT_EL_ID = os.environ.get('IBEAM_TWO_FA_INPUT_EL_ID', 'ID@@chlginput')
"""HTML element to input 2FA code into"""
...
TWO_FA_SELECT_EL_ID = os.environ.get('IBEAM_TWO_FA_SELECT_EL_ID', 'ID@@sf_select')
"""HTML element check for if Gateway requires to select the 2FA method.""" My first guess is as follows:
My suggestion is to: Hence:
|
@Voyz
Note that the timestamps between 'Submitting the form' and the 'Timeout' are approximately 180 secs,. I've changed the value of It appears that the IBEAM_PAGE_LOAD_TIMEOUT is not being triggered - it is being triggered by IBEAM_OAUTH_TIMEOUT and the timeout is happening because the 2FA verification field is not visible.
So if understand this correctly - the needed information for 2FA does exist. It must be that is just not showing up on the page.
|
If you're running it within a Docker container, there is no need to install the chromedriver. The image already has one. Yes, the page loads - note log
Yes indeed, that is the case. The Gateway stays open during all that process, hence you can do what you're suggesting at any point after seeing |
Thanks Voyz! I still working on being able to access the login screen manually. I appears that I can access the server @ Additionally I added the screenshot of the login screen that is dumped by setting the Am I moving in the right direction? |
Yes, Access Denied is a common error that can be easily solved most of the time. See here: https://github.com/Voyz/ibeam/wiki/Troubleshooting#access-denied. It involves modifying the And great job providing and analysing the screenshot. Indeed, it seems like the elements are rendered fine, but just need a different ID or class match pattern 👍 |
Gentlemen - Just to recap what Voy previously wrote: **My first guess is as follows: Your instance receives a slightly different version of the loading page - this happens sometimes, no idea why. And per his guidance: That being said - here is what I have discovered:
As a result I tried to override
Upon retrying to re-run the IBeam server - I get the following errors:
What would you recommend as next steps? Thanks! |
Great job debugging this. Therefore this confirms my earlier guesses. That indeed should be the root cause of the issue you're facing. You'd need to change the env vars as you deduce.
Can I suggest that you set this to:
Without the single quotes? Additional context: I have a feeling this causes the issue you're encountering now. We're doing a split at self.type = "'ID"
self.identifier = "xyz-field-silver-response'" Which doesn't match the target-identification pattern due to these single quotes. This seems to be confirmed when I look at the log you report and notice that the variable logged contains these quotes:
While the exception raising code itself doesn't introduce these quotes: raise RuntimeError(f'Unknown target type: {type}@@{identifier}') Hence, I assume the single quotes are indeed passed over from the env var and should be removed. Let me know if that works 👍 |
Sorry, thanks for pointing this out and apologies for misleading you here. The variable that IBeam uses to discover the 2FA prompt is
I think that should work, once again sorry for not spotting that sooner. Let me know 👍 |
SUCCESS! |
Again - Athousand thanks Voy.
Just out of curiosity - can you give quick description of how that mech
I've been reading the code
but obviously I'm missing something. :)
…On Tue, May 21, 2024 at 11:43 AM voyz ***@***.***> wrote:
Sorry, thanks for pointing this out and apologies for misleading you here.
The variable that IBeam uses to discover the 2FA prompt is
IBEAM_TWO_FA_EL_ID not IBEAM_TWO_FA_INPUT_EL_ID. That being said, that
second one also needs to be modified to xyz-field-silver-response, as it
is where we will type in the 2FA code. Hence:
IBEAM_TWO_FA_EL_ID=ID@@xyz-field-silver-response
IBEAM_TWO_FA_INPUT_EL_ID=ID@@xyz-field-silver-response
I think that should work, once again sorry for not spotting that sooner.
Let me know 👍
—
Reply to this email directly, view it on GitHub
<#185 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADMDCZ575K2VKNBAOEIHRZDZDNTR3AVCNFSM6AAAAABHULOYK6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRSHEYTSNZXGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Superb news @xjcarter 🥳🥳 Glad to see we've figured it out. Good job! 👏 Sorry, as for your question, it seems to have been cut off, all I see is:
|
Just out of curiosity - |
Ahh understood. IBeam interacts with the webpage using Selenium. If you're not familiar with it - it is a library used for browser automation, ie. being able to programmatically interact with a browser. In fact, we can even interact with it without displaying anything, just "pretending there is a display". Sort of like solving a Rubics cube blind folded. And that's what IBeam does: it loads the login page without a display, finds the right input fields, types in our credentials and hits the 'Login' button. The complexity comes in due to the fact that there are a bunch of versions of that webpage that IBKR servers - as you've unfortunately noticed in this Issue - and there are various control flows - eg. there are 4 ways to complete 2FA. Hence, we need to recognise all of these and act accordingly. That's what login_handler.py is doing, along with a bunch of functionalities that improve the experience, such as automatic shutdown on critical errors, error handling, screenshots, 2FA acquisition, etc. Hope that helps 👍 |
Very helpful.
Thanks!
…On Thu, May 23, 2024 at 1:54 AM voyz ***@***.***> wrote:
Ahh understood. IBeam interacts with the webpage using Selenium. If you're
not familiar with it - it is a library used for browser automation, ie.
being able to programmatically interact with a browser. In fact, we can
even interact with it without displaying anything, just "pretending there
is a display". Sort of like solving a Rubics cube blind folded. And that's
what IBeam does: it loads the login page without a display, finds the right
input fields, types in our credentials and hits the 'Login' button. The
complexity comes in due to the fact that there are a bunch of versions of
that webpage that IBKR servers - as you've unfortunately noticed in this
Issue - and there are various control flows - eg. there are 4 ways to
complete 2FA. Hence, we need to recognise all of these and act accordingly.
That's what login_handler.py is doing, along with a bunch of
functionalities that improve the experience, such as automatic shutdown on
critical errors, error handling, screenshots, 2FA acquisition, etc. Hope
that helps 👍
—
Reply to this email directly, view it on GitHub
<#185 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADMDCZ6VW4IVKQGEVYNCSKLZDWABLAVCNFSM6AAAAABHULOYK6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMRWGI4TANBQGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Hi All!
I am attempting to set up my 2FA automated authentication within IBeam
and have hit a roadblock I have been frantically trying to debug before asking for your help.
To be quick - here's the situation.
I have set up a server endpoint
http://{cloud_ip:cloud_port}/sms/code
that returns the IBRK authentication code.NOTE The response is NOT wrapped in JSON - just the string of the authenticaton code.
Per the wiki, I assume that is what IBeam is expecting. Is that correct?
I have thoroughly tested my 'auth_code_server' and it works as expected:
a. When IBeam triggers an authentication SMS from IBRK- the message is caught by the server and correctly parsed
and is ready to provide the desired auth code to IBeam via a GET request to the
http://{cloud_ip:cloud_port}/sms/code
endpoint.b. the needed firewall port for the 'auth_code_server' is open - and tests have accessed it outside being on localhost.
(I have manually logged into my live IBRK account from which the external server catches and saves the authentication code correctly)
c. How long does IBeam wait to get that authentication code? And which IBEAM environment variable controls that?
I dumped all my IBeam variables in an 'env.list' file which is the following:
Specifically:
1. Why doesn't my
IBEAM_EXTERNAL_REQUEST_URL
show up in my 'Configuration' dictionary?(Oddly-
IBEAM_TWO_FA_HANDLER=EXTERNAL_REQUEST
does appear in the dictionary)2. Should I define each of the environment variables needed for
IBEAM_TWO_FA_HANDLER=EXTERNAL_REQUEST
explicitly? I was assumimg the defaults for
IBEAM_TWO_FA_HANDLER=EXTERNAL_REQUEST
to be set.My IBeam launch:
$ docker run --rm --name ibeam --env-file /root/ibeam_files/env.list --network tradenet -p 5000:5000 -v /root/ibeam_files/inputs_directory/:/srv/inputs -v /root/ibeam_files/outputs:/srv/outputs:rw voyz/ibeam:0.5.3
The Log:
Here's my auth_server_code:
Thanks again for all your time, patience and help!
The text was updated successfully, but these errors were encountered: