Skip to content Skip to sidebar Skip to footer

How To Protect Custom Endpoints Using Basicauth?

Say I have enabled authentication to the resources using BasicAuth: class MyBasicAuth(BasicAuth): def check_auth(self,username,password,allowed_roles,resource,method):

Solution 1:

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':

defauth_resource(resource):
deffdec(f):
    @wraps(f)defwrapped(*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.

Solution 2:

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')defhello_world():
    return'Hello World!'if __name__ == '__main__':
    app.run()

Solution 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

defcheck_blueprint_auth():
    if'Authorization'notin 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 = Noneif header isNoneelse header['username']
    password = Noneif header isNoneelse 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 functionfrom 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'])defpost_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 blueprintfrom 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.

Post a Comment for "How To Protect Custom Endpoints Using Basicauth?"