Skip to content

Commit

Permalink
expose the jwt token fields using the flask.g variable (#5)
Browse files Browse the repository at this point in the history
Expose the jwt token fields using the flask.g variable
  • Loading branch information
bretkikehara authored and rs committed May 20, 2016
1 parent 97d0380 commit 884a887
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 6 deletions.
44 changes: 44 additions & 0 deletions README.rst
Expand Up @@ -45,6 +45,50 @@ If access is granted, the authentication module exposes roles and token's claims
if 'somerole' in auth.get_authen_roles():
# grant some finer access


Securing custom routes
-------------

JWT Authorization can be applied to any custom routes using the `@requires_token` wrapper. This annotation will only provide *audience and role access control*. User level access must be written manually.

from eve_auth_jwt import requires_token, get_request_auth_value

@app.route('/my_resource/download', methods=['GET'])
@requires_token(audiences=['myAudience'])
def csv_download():
# Allows all users with myAudience to access download
account_id = get_request_auth_value()

if check_user(account_id):
abort(401)

return generateCSV(account_id)

Here is an example of `myAdmin` access control:

from eve_auth_jwt import requires_token

@app.route('/admin/my_resource/download', methods=['GET'])
@requires_token(audiences=['myAudience'], allowed_roles=['myAdmin'])
def csv_download():
account_id = request.args.get('account_id', None)

return generateCSV(account_id)


Access the parsed JWT token values
-------------

The parsed JWT token values are stored in the `flask.g` dict, but custom functions exist to aid in reading the values. The values are only available after the JWT token integrity check and user authorization occurs.

from eve_auth_jwt import get_request_auth_value, get_authen_claims, get_authen_roles


def my_fn():
account_id = get_request_auth_value()
payload = get_authen_claims()
roles = get_authen_roles()

Licenses
--------

Expand Down
2 changes: 1 addition & 1 deletion eve_auth_jwt/__init__.py
@@ -1 +1 @@
from .auth import JWTAuth, requires_token
from .auth import JWTAuth, requires_token, get_authen_claims, get_authen_roles, get_request_auth_value
85 changes: 80 additions & 5 deletions eve_auth_jwt/auth.py
Expand Up @@ -8,21 +8,26 @@
from .verify_token import verify_token


AUTHEN_CLAIMS = 'authen_claims'
AUTHEN_ROLES = 'authen_roles'
AUTH_VALUE = 'auth_value'


class JWTAuth(BasicAuth):
"""
Implements JWT token validation support.
"""
def set_authen_claims(self, claims):
g.authen_claims = claims
setattr(g, AUTHEN_CLAIMS, claims)

def get_authen_claims(self):
return g.get('authen_claims', {})
return g.get(AUTHEN_CLAIMS, {})

def set_authen_roles(self, roles):
g.authen_roles = roles
setattr(g, AUTHEN_ROLES, roles)

def get_authen_roles(self):
return g.get('authen_roles', [])
return g.get(AUTHEN_ROLES, [])

def authorized(self, allowed_roles, resource, method):
authorized = False
Expand Down Expand Up @@ -93,14 +98,84 @@ def check_token(self, token, allowed_roles, resource, method):
return True


def set_authen_claims(claims):
"""
Set the authentication claims
Parameters:
claims (dict[str]): JWT claims
"""
setattr(g, AUTHEN_CLAIMS, claims)


def get_authen_claims():
"""
Get the authentication claims
Returns:
dict[str]: JWT claims
"""
return g.get(AUTHEN_CLAIMS, {})


def set_authen_roles(roles=[]):
"""
Get the authentication roles
Parameters:
roles (arr[str])
"""
setattr(g, AUTHEN_ROLES, roles)


def get_authen_roles():
"""
Get the authentication roles
Returns:
arr[str]: Array of associated roles
"""
return g.get(AUTHEN_ROLES, [])


def set_request_auth_value(value=None):
"""
Sets the current request's auth value
Parameters:
value (str|None): The request auth value
"""
setattr(g, AUTH_VALUE, value)


def get_request_auth_value():
"""
Get the authentication value
Returns:
str: auth value string
"""
return g.get(AUTH_VALUE)


def requires_token(audiences=[], allowed_roles=[]):
def requires_token_wrapper(f):
@wraps(f)
def decorated(*args, **kwargs):
token = request.args.get('access_token')
verified, _, _, _ = verify_token(token, request.method, audiences, allowed_roles)
verified, payload, account_id, roles = verify_token(token, request.method, audiences, allowed_roles)
if not verified:
abort(401)

# Save roles for later access
set_authen_roles(roles)

# Save claims for later access
set_authen_claims(payload)

# Limit access to the authen account
set_request_auth_value(account_id)

return f(*args, **kwargs)
return decorated
return requires_token_wrapper

0 comments on commit 884a887

Please sign in to comment.