Eve Negotiable authentication
Project description
eve-negotiable-auth
An advanced yet easy to use auth module for APIs built on Eve.
The auth class that ships with Eve, BasicAuth
, allows users of your API to authenticate with Basic Authentication. The NegotiableAuth
class in this package extends this to allow the user to choose from any authentication scheme your API supports. This allows for easy configuration and handling of multiple auth schemes - including schemes like Digest which require negotiation.
NOTE: This package is near-production ready. Before calling it 1.0 it needs better docs and perhaps a bit more tweaking. It is already in use in a number of production systems - but use at your own risk!
Getting Started
The steps are:
- Create a handler functions for each scheme you support
- Register those functions with AUTH_PARSER
- Extend
NegotiableAuth
and overrideprocess_claims()
Step 1 - Create handler functions
To handle a scheme you must define at least one function, usually two, which the authparser library will call. You can name them however you like - authparser calls them user_record_fn and challenge_fn
user_record_fn(token, **kwargs)
challenge_fn(**kwargs)
[optional - see authparser for details, mandatory for schemes likeDigest
]
This is best described with an example. Let's say you want to handle Bearer
token authorization. When the time comes to validate the token, your user_record_fn will be called. So let's create it. I'll call it handle_bearer
:
def handle_bearer(token, **kwargs):
# do stuff to validate the token
# ...
# if it checks out, populate the user record:
record = {
'user': 'someone@example.com',
'role': 'employee'
}
# if there is a problem (if NegotiableAuth sees '_issues' then it will deny access):
record = {
'_issues': {
'token': 'The token has expired.'
}
}
return record
Step 2 - Register the handler functions
The best place to do this is above the class definition you will create in step 3. I will start by creating a file named my_auth.py
from eve_negotiable_auth import NegotiableAuth, AUTH_PARSER
from --wherever you defined your handler-- import handle_bearer
AUTH_PARSER.add_handler('Bearer', handle_bearer)
Now when the time comes, NegotiableAuth
will know if it receives a request whose Authorization
header has a Bearer
token, it will call your handle_bearer()
function.
Step 3 - Extend NegotiableAuth
and override process_claims()
The NegotiableAuth
class is an abstract base class and cannot be used on its own. You must make your own class that inherits from it. There is only one function to override: process_claims()
.
Building on the my_auth.py
we started in step 2:
from eve_negotiable_auth import NegotiableAuth, AUTH_PARSER
from --wherever you defined your handler-- import handle_bearer
class MyAuth(NegotiableAuth):
def __init__(self):
super(MyAuth, self).__init__()
def process_claims(self, claims, allowed_roles, resource, method):
authorized = 'user' in claims
role = claims.get('role')
if resouce = 'salary' and role != 'employer':
authorized = False
if resource == 'position' and method != 'GET' and role != 'employer':
authorized = False
return authorized
This is a too-simple example for illustration only. The request will be authorized if user
exists in claims, unless the request is for salary
then only employers are allowed. If it is a GET
request for position
, it is allowed for everyone - only employers can POST
, PUT
, DELETE
, etc.
There are many things you can do in your own process_claims()
. Please read the Eve docs for more details.
The things you need to know:
claims
is the record returned from your handler function.- If the handler returns falsey, or dict with
_issues
, it will reject the request before your class'sprocess_claims()
is called - your
process_claims()
need only returnTrue
orFalse
, depending whether theclaims
is allowed in or not. - As you see, you are in full control of what's in
claims
and how to determine whether to grant access based on what is in theclaims
.
- If the handler returns falsey, or dict with
allowed_roles
,resource
, andmethod
are passed in from Eve depending on the request and what is in your Eve settings.- If you are using Eve's User-Restricted Resource Access, process_claims() is where you will call
self.set_request_auth_value()
Wire it into your project
Once you have defined your auth class, add it to your Eve app. When you instantiate the app, pass the class name as the auth
param.
app = Eve('app-name', auth=MyAuth)
Beyond the Basics
When NegotiableAuth
calls your handler function, it passes the following kwargs to get_user_record()
- allowed_roles
- resource
- method
- request - the flask request object
When you define that function, have it return an dict with each member a claim (e.g. username, email, role). If the function returns falsey, or a dict that has a member named _issues
, then access will be denied. To communicate issues back to the requestor, have _issues
be a dict of name/value pairs, for example (this example has just one name/value):
{
'_issues': {
'user': 'This user does not exist.'
}
}
get_challenge_header()
- passed through to the scheme's challenge_fn
- request
...more docs coming soon...
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file eve-negotiable-auth-0.9.5.tar.gz
.
File metadata
- Download URL: eve-negotiable-auth-0.9.5.tar.gz
- Upload date:
- Size: 5.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5f8641996eb587ded1565fe65fd62c61d05470166758e43cbdf04a6c40ec015f |
|
MD5 | dae6fe06f244b4b595bcb3b43d0dd017 |
|
BLAKE2b-256 | 7d6787d3da1095b7d081b9341f2ea37cddfb28594830671562e217978a837b10 |
File details
Details for the file eve_negotiable_auth-0.9.5-py3-none-any.whl
.
File metadata
- Download URL: eve_negotiable_auth-0.9.5-py3-none-any.whl
- Upload date:
- Size: 6.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.9.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f2ab117d9588ad187743911daae985ce1a7a50de8517e8b8fb7a8683253e9380 |
|
MD5 | f28bb0dd01ce440cc3862d436779b20a |
|
BLAKE2b-256 | 44fc87670dbd3049c644c0b1d2e35a2f06ca2f65b3f6b8f024bbdb3121432385 |