pallets-eco / flask-security

Quick and simple security for Flask applications
MIT License
1.63k stars 513 forks source link

SECURITY_POST_LOGIN_VIEW conflict with 'next' #850

Open cwohlers opened 4 years ago

cwohlers commented 4 years ago

I'm having an issue with SECURITY_POST_LOGIN_VIEW that appears identical to https://github.com/mattupstate/flask-security/issues/263 and is probably related to https://github.com/mattupstate/flask-security/pull/261 except that I'm running Flask-Security version 3.0.0.

I'm setting my config var as

SECURITY_POST_LOGIN_VIEW = '/logged_in'

If I originate from /login exactly, the SECURITY_POST_LOGIN_VIEW works as anticipated. However users visiting / get redirected to /login?next=%2F and SECURITY_POST_LOGIN_VIEW does not work when they login.

It seems like this is an issue that has already been encountered and I'm not properly addressing something? Any thoughts?

jwag956 commented 4 years ago

I have cloned this issue to my 'fork'.

This behavior goes way back - basically - when redirecting (post login, post register, post logout) it will look first at request.args.next, then request.form.next and THEN the config view. IMHO this isn't incorrect behavior it might be worth some new configuration options - (and certainly some additional docs).

To do what you want is actually pretty easy: def unauth(): return flask.redirect(flask.url_for('security.login'))

security.login_manager.unauthorized_handler(unauth)

see if that works for you.

cwohlers commented 4 years ago

Hey @jwag956, thanks for the input! I did try using the login_manager.unauthorized_handler previously. It does successfully reroute everything to /login but I actually don't want ALL unauthorized calls to reroute to /login.

For my use case I only want calls to the root endpoint (eg '/' or '/index') to utilize the SECURITY_POST_LOGIN_VIEW redirect. I would like to preserve the next value for users trying to got to other urls (eg '/profile?<query string>').

In theory I should be able to conditionally redirect in the unauth() function BUT what I've found is that FLASK-SECURITY already reroutes the request BEFORE login_manager.unauthorized_handler() is called and none of the REQUEST data is preserved. If I try to visit '/profile', by the time I have access to the request object in unauth() the endpoint has reverted to 'index' and the path is u'/'

Is there a way I could get access to the original request object for conditional rerouting?

jwag956 commented 4 years ago

Not quite sure your setup. But if you decorate your method with @login_required, and you aren't authenticated, 'unauth' will be called prior to anything in FS being called (assuming you are using session cookies and not auth tokens.