Azure-Samples / ms-identity-python-webapp

A Python web application calling Microsoft graph that is secured using the Microsoft identity platform
MIT License
279 stars 133 forks source link

Session's not persistent ... #127

Closed NexPlex closed 5 months ago

NexPlex commented 5 months ago

Hi I was able to get this module to work correctly on windows Python 3.9.9

when I move it to docker python:3.9.16 it looses session information between log_in() and complete_log_in(). I've tried many different versions of Flask-Session and CORS but nothing seems to make a difference.

I'm getting this error. The web page with complete_log_in() MUST be visited after the web page with log_in()

rayluo commented 5 months ago

I don't know how you "move it to docker" but, simply put, this sample stores session on file system by default.

Perhaps you can run it normally i.e. outside of docker, and then check where those sessions are stored (probably ./flask_session/*), and then you would need to figure out how that path would be mounted as a persist-able volume in docker.

NexPlex commented 5 months ago

Hi, thank you for the quick reply. to "move it to docker." Using the docker desktop, I copy the PY code to an existing docker container. I also recomposed the container to ensure it has the same requirements and module versions.

I am a little familiar with flask_sessions, and before contacting you, I verified that ./flask_session/* existed. I also made this change

SESSION_TYPE = "filesystem"

SESSION_TYPE = "sqlalchemy"
SESSION_SQLALCHEMY_TABLE = 'flask_sessions'

Using both print statements and monitoring the SQL table "flask_sessions" I see a new session is being created on each router. The session seems to exist with the session data but a new session is created on the 2nd route.

In my use case the /login route is called from an angular front end. instead of using the template I use return redirect(login_url) like this.

After further investigation, my build works fine in Windows and docker Linux if I use localhost. when I use a fqdn on these routes it seems to create a new session


@msauth.route("/login")
@cross_origin() 
def login():
redirect_uri = app.config['APP_BACKEND_SERVER'] + '/v1/msauth' + auth_ms_config.REDIRECT_PATH

    login_url = auth.log_in(
        scopes=auth_ms_config.SCOPE,  # Have user consent to scopes during log-in
        redirect_uri=redirect_uri,
        # Optional. If present, this absolute URL must match your app's redirect_uri registered in Azure Portal
        prompt="select_account",
        # Optional. More values defined in  https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
    )['auth_uri']

    print('session login', session)

    return redirect(login_url)`

@msauth.route(auth_ms_config.REDIRECT_PATH)
# @cross_origin()
def auth_response():
    # https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference
    auth_flow = session.get('_auth_flow', {})
    print('auth_flow', auth_flow)
    print('session auth_response', session)
    result = auth.complete_log_in(request.args)
    if "error" in result:
        return render_template("ms_auth/auth_error.html", result=result)

I had similar issues before and fixed it using msauth = Blueprint('msauth', name) CORS(msauth)

And on the route @cross_origin(supports_credentials=True)

Any other suggestionis

rayluo commented 5 months ago

Hi, thank you for the quick reply.

My pleasure.

to "move it to docker." Using the docker desktop, I ...

In my use case the /login route is called from an angular front end. instead of using the template I use return redirect(login_url) like this.

After further investigation, my build works fine in Windows and docker Linux if I use localhost. when I use a fqdn on these routes it seems to create a new session


@msauth.route("/login")
@cross_origin() 
def login():
    ...
    return redirect(login_url)`

@msauth.route(auth_ms_config.REDIRECT_PATH)
# @cross_origin()
def auth_response():
    ...
    if "error" in result:
        return render_template("ms_auth/auth_error.html", result=result)

I had similar issues before and fixed it using msauth = Blueprint('msauth', name) CORS(msauth)

And on the route @cross_origin(supports_credentials=True)

Any other suggestionis

Sounds like you have a delicate setup. Perhaps you can double check whether your redirect_uri is using the same FQDN as the rest of your routes. Other than that, I don't really have a theory off the top of my head. Our off-the-shelf sample has been deployed to App Service as-is, and App Service is a container, so, this sample is known to work inside a container with a non-localhost fqdn (as your_site.azurewebsites.net), without much hustle.

The blueprint is also on our roadmap, however we do not currently have an ETA. We will keep this issue open. Once we have a new version available in a feature branch, I hope I'll remember to ping you in this issue so that you can have a try. In case I would forget, please subscribe/watch this repo (via its homepage on github), so that you will receive its release notification.

NexPlex commented 5 months ago

You are right. We have one app supporting several domains. The problem is with using the wrong domain in the redirect_uri.

Thank you. and a great module.

rayluo commented 5 months ago

Thanks for sharing your solution! We will somehow mention this info somewhere, so that the community will benefit from your exploration.

Cheers!