How to protect custom endpoints using BasicAuth?

梦想的初衷 提交于 2019-12-12 15:55:20

问题


Say I have enabled authentication to the resources using BasicAuth:

class MyBasicAuth(BasicAuth):
    def check_auth(self,username,password,allowed_roles,resource,method):
        return username == 'secretusername' and password == 'secretpass'

I also have custom routes which are used to manage documents from a HTML view. How do I use the same MyBasicAuth to protect the all the custom routes? I also need to implement logic which authenticates using the above MyBasicAuth. Please help me with this. It's for personal use, so I preferred hard coding the username and password.


回答1:


You can leverage the requires_auth decorator which is used internally by Eve itself. That way, your auth class will also be used to protect your custom routes:

from eve import Eve
from eve.auth import requires_auth

app = Eve()

@app.route('/hello')
@requires_auth('resource')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()



回答2:


If you are trying to use a custom end-point Authentication you will find it difficult as mentioned here: https://github.com/pyeve/eve/issues/860 I ended up writing a wrapper to get around the issue of 'resource' not being passed to 'requires_auth':

def auth_resource(resource):
def fdec(f):
    @wraps(f)
    def wrapped(*args, **kwargs):
            return f(resource=resource, *args, **kwargs)
    return wrapped
return fdec

This way you can define in your DOMAIN an authentication class:

DOMAIN = {
    'testendpoint'= {'authentication':MyCustomAuthetication},
    'otherendpoints'=...

And in my app I have wrapped the requires_auth decorator and added this as a authentication resource.

@app.route('/testendpoint/<item>', methods=['GET'])
@auth_resource('testendpoint')
@requires_auth('item')
def my_end_point_function(*args, **kwargs):
    dosomthinghere

As long as an authentication class is defined in the settings file for an endpoint, this also allows you to reuse any authentication defined in another endpoint which may be handy if you want to make sure all the endpoints use the same authentication.




回答3:


If you are using flask blueprints for your custom routes, you can add a before request function for your blueprint to do that.

First, create a function to check authentication from blueprints. You need to get the Authorization header from the flask request by yourself, like this:

from flask import request, abort, current_app
from werkzeug.http import parse_authorization_header

def check_blueprint_auth():
    if 'Authorization' not in request.headers:
        print('Authorization header not found for authentication')
        return abort(401, 'Authorization header not found for authentication')
    header = parse_authorization_header(request.headers['Authorization'])
    username = None if header is None else header['username']
    password = None if header is None else header['password']

    return username == 'secretusername' and password == 'secretpass'

Then, you can set this function to be called before each blueprint's request. Below is an example of a blueprint definition, setting the before_request function:

from flask import Blueprint, current_app as app
# your auth function
from auth import check_blueprint_auth

blueprint = Blueprint('prefix_uri', __name__)

# this sets the auth function to be called
blueprint.before_request(check_blueprint_auth)


@blueprint.route('/custom_route/<some_value>', methods=['POST'])
def post_something(some_value):
#  something

Finally, you need to bind the blueprint with your eve app. An example on how to bind blueprints, taken in part from here:

from eve import Eve
# your blueprint
from users import blueprint
from flask import current_app, request

app = Eve()
# register the blueprint to the main Eve application
app.register_blueprint(blueprint)

app.run()

Hope that helps.



来源:https://stackoverflow.com/questions/38160290/how-to-protect-custom-endpoints-using-basicauth

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!