Skip to main content
This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (pypi.python.org).
Help us improve Python packaging - Donate today!

JWT authentication policy for Pyramid

Project Description

JWT authentication for Pyramid

This package implements an authentication policy for Pyramid that using JSON Web Tokens. This standard (RFC 7519) is often used to secure backens APIs. The excellent PyJWT library is used for the JWT encoding / decoding logic.

Enabling JWT support in a Pyramid application is very simple:

from pyramid.config import Configurator
from pyramid.authorization import ACLAuthorizationPolicy

def main():
    config = Configurator()
    # Pyramid requires an authorization policy to be active.
    config.set_authorization_policy(ACLAuthorizationPolicy())
    # Enable JWT authentication.
    config.include('pyramid_jwt')
    config.set_jwt_authentication_policy('secret')

This will set a JWT authentication policy using the Authorization HTTP header with a JWT scheme to retrieve tokens. Using another HTTP header is trivial:

config.set_jwt_authentication_policy('secret', http_header='X-My-Header')

To make creating valid tokens easier a new create_jwt_token method is added to the request. You can use this in your view to create tokens. A simple authentication view for a REST backend could look something like this:

@view_config('login', request_method='POST', renderer='json')
def login(request):
    login = request.POST['login']
    password = request.POST['password']
    user_id = authenticate(login, password)  # You will need to implement this.
    if user_id:
        return {
            'result': 'ok',
            'token': request.create_jwt_token(user_id)
        }
    else:
        return {
            'result': 'error'
        }

Since JWT is typically used via HTTP headers and does not use cookies the standard remember() and forget() functions from Pyramid are not useful. Trying to use them while JWT authentication is enabled will result in a warning.

Extra claims

Normally pyramid_jwt only makes a single JWT claim: the subject (or sub claim) is set to the principal. You can also add extra claims to the token by passing keyword parameters to the create_jwt_token method.

token = request.create_jwt_token(user.id,
    name=user.name,
    admin=(user.role == 'admin'))

All claims found in a JWT token can be accessed through the jwt_claims dictionary property on a request. For the above example you can retrieve the name and admin-status for the user directly from the request:

print('User id: %d' % request.authenticated_userid)
print('Users name: %s', request.jwt_claims['name'])
if request.jwt_claims['admin']:
   print('This user is an admin!')

Keep in mind that data jwt_claims only reflects the claims from a JWT token and do not check if the user is valid: the callback configured for the authentication policy is not checked. For this reason you should always use request.authenticated_userid instead of request.jwt_claims['sub'].

You can also use extra claims to manage extra principals for users. For example you could claims to represent add group membership or roles for a user. This requires two steps: first add the extra claims to the JWT token as shown above, and then use the authentication policy’s callback hook to turn the extra claim into principals. Here is a quick example:

def add_role_principals(userid, request):
   return ['role:%s' % role for role in request.jwt_claims.get('roles', [])]

config.set_jwt_authentication_policy(callback=add_role_principals)

You can then use the role principals in an ACL:

class MyView:
    __acl__ = [
        (Allow, Everyone, ['read']),
        (Allow, 'role:admin', ['create', 'update']),
    ]

Validation Example

After creating and returning the token through your API with create_jwt_token you can test by issuing an HTTP authorization header type for JWT.

GET /resource HTTP/1.1
Host: server.example.com
Authorization: JWT eyJhbGciOiJIUzI1NiIXVCJ9...TJVA95OrM7E20RMHrHDcEfxjoYZgeFONFh7HgQ

We can test using curl.

curl --header 'Authorization: JWT TOKEN' server.example.com/ROUTE_PATH
config.add_route('example', '/ROUTE_PATH')
@view_config(route_name=example)
def some_action(request):
    if request.authenticated_userid:
        # Do something

Settings

There are a number of flags that specify how tokens are created and verified. You can either set this in your .ini-file, or pass/override them directly to the config.set_jwt_authentication_policy() function.

Parameter ini-file entry Default Description
private_key jwt.private_key   Key used to hash or sign tokens.
public_key jwt.public_key   Key used to verify token signatures. Only used with assymetric algorithms.
algorithm jwt.algorithm HS512 Hash or encryption algorithm
expiration jwt.expiration   Number of seconds (or a datetime.timedelta instance) before a token expires.
leeway jwt.leeway 0 Number of seconds a token is allowed to be expired before it is rejected.
http_header jwt.http_header Authorization HTTP header used for tokens
auth_type jwt.auth_type JWT Authentication type used in Authorization header. Unused for other HTTP headers.
json_encoder   None A subclass of JSONEncoder to be used to encode principal and claims infos.

Changelog

1.2 - May 25, 2017

1.1 - May 4, 2016

  • Issue #2: Support setting and reading extra claims in a JWT token.
  • Pull request #4: Fix parsing of expiration and leeway settings from a configuration value. Submitted by Daniel Kraus.
  • Pull request #3: Allow overriding the expiration timestamp for a token when creating a new token. Submitted by Daniel Kraus.

1.0 - December 17, 2015

  • First release
Release History

Release History

This version
History Node

1.2

History Node

1.1

History Node

1.0

Download Files

Download Files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
pyramid_jwt-1.2-py2.py3-none-any.whl (10.1 kB) Copy SHA256 Checksum SHA256 2.7 Wheel May 25, 2017
pyramid_jwt-1.2.tar.gz (8.9 kB) Copy SHA256 Checksum SHA256 Source May 25, 2017

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting