jfinkels / flask-restless

NO LONGER MAINTAINED - A Flask extension for creating simple ReSTful JSON APIs from SQLAlchemy models.
https://flask-restless.readthedocs.io
GNU Affero General Public License v3.0
1.02k stars 301 forks source link

Adding HTTP basic authentication #513

Open klothe opened 8 years ago

klothe commented 8 years ago

I'd like to add HTTP basic authentication to a Flask-Restless API. I've seen the documentation on using preprocessors for authentication, but I'm not sure how to use a preprocessor with an existing library for HTTP authentication.

I would normally use Flask-HTTPAuth for HTTP basic authentication in a Flask app. But the @auth.login_required decorator in Flask-HTTPAuth is meant to decorate regular Flask functions and can't be used as a Flask-Restless preprocessor. I'd like to avoid having to decode the Authorization header and parse it, etc.

I'm sure I'm not the first one to encounter this issue, so are there any examples of a good way to do it?

jfinkels commented 8 years ago

Would this be solved by issue #497?

klothe commented 8 years ago

Yes, that sounds like a good feature. But this is more of a question--is there already a relatively simple way do HTTP basic authentication with Flask-Restless?

jfinkels commented 8 years ago

I can't think of a good way to use Flask-HTTPAuth, for example, without allowing user-specified decorators on view methods, as described in issue #497, but I haven't personally tried.

0xC4N1 commented 8 years ago

For simple authentication via Authentication header you could use Flask-Login, define your request_loader to check the credentials in the Authentication header and use an api endpoint preprocessor that checks flask.ext.login.current_user.is_authorized. If is_authorized is False, throw a ProcessingException with a 401 Unauthorized status.

True HTTP Basic Authentication is a little tricky with flask-restless thought. As specified in rfc1945#section-10.16 the first request is done without Authentication header. The server needs to respond with an unauthorized status and a WWW-Authenticate header to make the client send another request with Authentication header and user credentials.

I have no clue how to add this header to the response that is generated when you throw ProcessingException in case of a missing Authentication header.

jfinkels commented 8 years ago

Thanks @4311021x. So if ProcessingException were modified with an additional_headers field, say, and Flask-Restless appended those headers to the response, would that be one way of solving this problem?

0xC4N1 commented 8 years ago

Yes that would be one way to implement the authentication process including Access Authentication. At least it works with Firefox when you do it that way. I didn't test it with other browsers. The @login_required decorator might be doing more than just replying with an unauthorized status and a WWW-Authenticate header thought. So supporting the decorator might be more elegant if you want to support all features of the authentication modules.