-
-
Notifications
You must be signed in to change notification settings - Fork 468
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
Azure OAuth CSRF State Not Equal Error #518
Comments
According to your description, it seems your app's session is not working properly.
|
Hi @lepture and thank you for your response. I hate to respond back like this, but how exactly would I go about doing these 2 things? I am not very experienced with authlib as well as FAB. I am just trying to run airflow and a part of airflow is the web UI which is built on FAB and authlib. I have never used authlib outside of this. I will try to find out where airflow sets up the flask app tomorrow, but any help or guidance about how I would do this, as well as make sure the session is working would be greatly appreciated. Thank you! |
@lepture I have found where the app gets created in airflow. The code is down below. I do not see a "secure_key" getting set, but I do see a "secret_key" being set ( flask_app.secret_key = conf.get('webserver', 'SECRET_KEY') ) So my question is how do I test to see if the session is working??
|
@lepture Have did some more debugging so wanted to add the information I gathered from it. It looks like this is a problem with the session. I added print statements to print the session in the framework_integration.py, and this is what it looks like: But yet when I try to print the name of the session with: print(session.get("name")) I get "None" as the value. So, the session is being created, but it is somehow empty. So the question is, why would the session be empty, and how do I go about fixing this? Here is a screenshot of the debugging messages I created within each of these files so you can see the flow it takes. |
@lepture I have did more debugging, and am back with another update to provide more information on this issue. Looks like I figured out what is happening but am unsure on how to fix. I have put in a ton of debugging statements to follow the flow of code to see what was happening in the background. But, in interest of keeping this update short, I will just summarize what I found and what I think is happening. We start in flask_appbuilder/security/views.py in the "def login(self, provider: Optional[str] = None) -> WerkzeugResponse:" function under the "AuthOAuthView(AuthView) class. This function returns a call to another function, "authorize_redirect". The function" authorize_redirect" is found in authlib/integrations/flask_client/apps.py at line 39. This function does a lot of things, but the most important is at the end when it calls "save_authorize_data". "save_authorize_data" is in the same file, and found at line 32. This function calls a function called "set_state_data". This leads us to authlib/integrations/base_client/framework_integration.py, where it sets the session data and returns. Before the function "Authorize_redirect" returns back to "views.py", I printed out the session to see what it looked like. This is what is printed: Clearly, you can see here that session has the correct state. So it returns the redirect url, and according to this in the return statement of the "login" function: "redirect_uri=url_for( ".oauth_authorized", provider=provider _external=True)" my guess is that the next place its going is the "oauth_authorized" function within the "views.py" file. So, I put print statements at the top of this file to print out the session, and this is what I get: So, somehow the redirect is causing the session to lose all its data… I will be investigating on this more Tuesday, but I hope you can help provide insight on how to fix. |
@lepture I have been stuck on finding out why the redirect is causing the session to lose all of its data, any help on how to debug and fix this? |
@ahipp13 You can debug your session issue with: @app.route('/set-session')
def set_session():
session['test'] = 'foo'
return 'set session'
@app.route('/read-session')
def read_session():
value = session.get('test', '')
return value
If you can not get the value, your application's session is not configured correctly. |
@lepture Where do I need to add this code? |
@lepture I have figured out where to add this code and have the results from testing. It took me awhile as I had to dig into Airflow's source code to see how they implemented the web app. I will explain what I edited to get it to work and then my results. What I had to do was edit the views.py file in the airflow source code (airflow/www/views.py). This is what I put in (the class starts at line 561):
I then redeployed my application. I went to the 2 urls like you said, and this is the output: As you can see, in the other browser I was unable to get the value. So it seems as if the session is no configured correctly. So my next question is, where do I find out where the session is configured, and what is configured wrong?? |
@ahipp13 You need to ask this question from airflow or flask-appbuilder. I'm not familiar with those things. |
I have finally found what the source of this problem was, as well as the solution. Doing more debugging, I found that the problem with the session was coming from the webserver_config.py file that I had created. So, what I did was started with as barebones of a Oauth Webserver_config.py file as I could, and kept adding lines until one of them screwed up the session. In doing this I found that it was this line: PERMANENT_SESSION_LIFETIME = 1800 That was causing the session to not persist. I am not too sure as to why. The reason I had put this in my webserver_config.py file in the first place is because it is in the FAB documentation(https://flask-appbuilder.readthedocs.io/en/latest/security.html#), but in further researching I found that it is already being set in the creation of the flask app by Airflow and is an configuration option: AIRFLOW__WEBSERVER__SESSION_LIFETIME_MINUTES Now why this worked in Airflow version 2.2.5 and not in Airflow 2.4.3, I am not for sure. Also through my debugging I found out that FAB natively supports Azure now, so a custom security class and user info handler function is not needed. So, to answer this question, the solution to my problem was to start using thie webserver_config.py file down below.
|
Cool. Yeah The technique when you start from "barebones" and start adding customizations is technique I often suggest users when we are not able to guess it by reviewing. Thanks for doing it and even more thanks for reporting back your investigation results - it might save countless hours for multiple people who might find the solution to their problems by reading this issue. This is one of the best contributions to the project you can make as a user 🎉 |
@potiuk Thank you! So currently the session_lifetime_minutes is not working. Is this the only way in Airflow to set the UI to timeout after a certain amount of time? For the airflow app I am working on we want users to be logged out of the UI after 30 minutes, so I am wondering if there is a different way to do this or if we currently cannot do this?? |
I am quite confused. I understood from your comment that the changes you applied DID solve your problem.
But maybe you have a different issue now. But - regardless - possibly you can check how it behaves in main after the CSRF timout to be the same as session timeout and see if it fixes the issue (pointed out to you in the other thread:" apache/airflow#28730 and it has nothing to do with authlib. You can even manually apply the same change and see if it fixes the problem. But if you still have the problem and it does not fix it - then by all means I encourage you to open a new issue - as this thread is now rather confusing whether thing are fixed or not. |
when i am using azure authentication in flask app builder getting this error : Error returning OAuth user info: %s 'upn'
i have got jwt token credentials are verified but getting UPN key error how can i resolve it |
Describe the bug
When I try to use Azure OAuth to log into my Airflow application, instead of logging me in I am sent back to the login page with a CSRF state mismatch error.
Error Stacks
To Reproduce
I am running Airflow 2.4.3 on Kubernetes pods using the airflow community helm chart 8.6.1(https://github.com/airflow-helm/charts) and python 3.8.15. To use Azure OAuth configuration with Airflow, I have created the webserver_config file to do so:
Expected behavior
When you hit the login button it should log me in to the airflow instance.
Environment:
Additional context
This was working just fine, but when we upgraded from airflow 2.2.5 to 2.4.3 this issue arose. Here are some current versions of libraries I have installed:
Airflow==2.4.3
Authlib==1.1.0
Flask-AppBuilder==4.1.4
Flask-Babel==2.0.0
Flask-Caching==2.0.1
Flask-JWT-Extended==4.4.4
Flask-Login==0.6.2
Flask-SQLAlchemy==2.5.1
Flask-Session==0.4.0
Flask-WTF==1.0.1
Flask==2.2.2
I have posted this issue in airflow as well as FAB and still have not been able to find out how to solve
The text was updated successfully, but these errors were encountered: