JWT authentication for Pyramid

Overview

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 backend 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')

If your application needs to decode tokens which contain an Audience claim you can extend this with:

config.set_jwt_authentication_policy('secret',
                                    auth_type='Bearer',
                                    callback=add_role_principals,
                                    audience="example.org")

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

Unless you are using JWT cookies within cookies (see the next section), the standard remember() and forget() functions from Pyramid are not useful. Trying to use them while regular (header-based) JWT authentication is enabled will result in a warning.

Using JWT inside cookies

Optionally, you can use cookies as a transport for the JWT Cookies. This is an useful technique to allow browser-based web apps to consume your REST APIs without the hassle of managing token storage (where to store JWT cookies is a known-issue), since http_only cookies cannot be handled by Javascript running on the page

Using JWT within cookies have some added benefits, the first one being sliding sessions: Tokens inside cookies will automatically be reissued whenever reissue_time is past.

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_cookie_authentication_policy(
        'secret', reissue_time=7200
    )

When working with JWT alone, there's no standard for manually invalidating a token: Either the token validity expires, or the application needs to handle a token blacklist (or even better, a whitelist)

On the other hand, when using cookies, this library allows the app to logout a given user by erasing its cookie: This policy follows the standard cookie deletion mechanism respected by most browsers, so a call to Pyramid's forget() function will instruct the browser remove that cookie, effectively throwing that JWT token away, even though it may still be valid.

See Creating a JWT within a cookie for examples.

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.
audience jwt.audience   Proposed audience for the token
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.

The follow options applies to the cookie-based authentication policy:

Parameter ini-file entry Default Description
cookie_name jwt.cookie_name Authorization Key used to identify the cookie.
cookie_path jwt.cookie_path None Path for cookie.
https_only jwt.https_only_cookie True Whether or not the token should only be sent through a secure HTTPS transport
reissue_time jwt.cookie_reissue_time None Number of seconds (or a datetime.timedelta instance) before a cookie (and the token within it) is reissued

Pyramid JWT example use cases

This is a basic guide (that will assume for all following statements that you have followed the Readme for this project) that will explain how (and why) to use JWT to secure/restrict access to a pyramid REST style backend API, this guide will explain a basic overview on:

  • Creating JWT's
  • Decoding JWT's
  • Restricting access to certain pyramid views via JWT's

Creating JWT's

First off, lets start with the first view in our pyramid project, this would normally be say a login view, this view has no permissions associated with it, any user can access and post login credentials to it, for example:

def authenticate_user(login, password):
    # Note the below will not work, its just an example of returning a user
    # object back to the JWT creation.
    login_query = session.query(User).\
        filter(User.login == login).\
        filter(User.password == password).first()

    if login_query:
        user_dict = {
            'userid': login_query.id,
            'user_name': login_query.user_name,
            'roles': login_query.roles
        }
        # An example of login_query.roles would be a list
        # print(login_query.roles)
        # ['admin', 'reports']
        return user_dict
    else:
        # If we end up here, no logins have been found
        return None

@view_config('login', request_method='POST', renderer='json')
def login(request):
    '''Create a login view
    '''
    login = request.POST['login']
    password = request.POST['password']
    user = authenticate(login, password)
    if user:
        return {
            'result': 'ok',
            'token': request.create_jwt_token(
                                            user['userid'],
                                            roles=user['roles'],
                                            userName=user['user_name']
                                            )
        }
    else:
        return {
            'result': 'error',
            'token': None
        }

Now what this does is return your JWT back to whatever front end application you may have, with the user details, along with their permissions, this will return a decoded token such as:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyTmFtZSI6Imx1a2UiLCJyb2xlcyI6WyJhZG1pbiIsInJlcG9ydHMiXSwic3ViIjo0LCJpYXQiOjE1MTkwNDQyNzB9.__KjyW1U-tpAEvTbSJsasS-8CaFyXH784joUPONH6hQ

Now I would suggest heading over to JWT.io, copy this data into their page, and you will see the decoded token:

{
  "userName": "luke",
  "roles": [
    "admin",
    "reports"
  ],
  "sub": 4,
  "iat": 1519044270
}

Note, at the bottom of jwt.io's webpage, that the signature shows verified, if you change the "secret" at the bottom, it will say "NOT Verified" this is because in order for any JWT process to be verified, the valid "secret" or "private key" must be used. It is important to note that any data sent in a JWT is accessible and readable by anyone.

Decoding JWT

The following section would also work if pyramid did not create the JWT, all it needs to know to decode a JWT is the "secret" or "private key" used to create/sign the original JWT.By their nature JWT's aren't secure, but they can be used "to secure". In our example above, we returned the "roles" array in our JWT, this had two properties "admin" and "reports" so we could then in our pyramid application, setup an ACL to map JWT permissions to pyramid based security, for example in our projects __init__.py we could add:

from pyramid.security import ALL_PERMISSIONS

class RootACL(object):
    __acl__ = [
        (Allow, 'admin', ALL_PERMISSIONS),
        (Allow, 'reports', ['reports'])
    ]

    def __init__(self, request):
        pass

What this ACL will do is allow anyone with the "admin" role in their JWT access to all views protected via a permission, where as users with "reports" in their JWT will only have access to views protected via the "reports" permission.

Now this ACL in itself is not enough to map the JWT permission to pyramids security backend, we need to also add the following to __init__.py:

from pyramid.authorization import ACLAuthorizationPolicy


def add_role_principals(userid, request):
    return request.jwt_claims.get('roles', [])

def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """
    config = Configurator(settings=settings)
    ...
    # Enable JWT - JSON Web Token based authentication
    config.set_root_factory(RootACL)
    config.set_authorization_policy(ACLAuthorizationPolicy())
    config.include('pyramid_jwt')
    config.set_jwt_authentication_policy('myJWTsecretKeepThisSafe',
                                        auth_type='Bearer',
                                        callback=add_role_principals)

This code will map any properties of the "roles" attribute of the JWT, run them through the ACL and then tie them into pyramids security framework.

Creating a JWT within a cookie

Since cookie-based authentication is already standardized within Pyramid by the remember() and forget() calls, you should simply use them:

from pyramid.response import Response
from pyramid.security import remember

@view_config('login', request_method='POST', renderer='json')
def login_with_cookies(request):
    '''Create a login view
    '''
    login = request.POST['login']
    password = request.POST['password']
    user = authenticate(login, password)  # From the previous snippet
    if user:
        headers = remember(
            user['userid'],
            roles=user['roles'],
            userName=user['user_name']
        )
        return Response(headers=headers, body="OK")  # Or maybe redirect somewhere else
    return Response(status=403)  # Or redirect back to login

Please note that since the JWT cookies will be stored inside the cookies, there's no need for your app to explicitly include it on the response body. The browser (or whatever consuming this response) is responsible to keep that cookie for as long as it's valid, and re-send it on the following requests.

Also note that there's no need to decode the cookie manually. The Policy handles that through the existing request.jwt_claims.

How is this secure?

For example, a JWT could easily be manipulated, anyone could hijack the token, change the values of the "roles" array to gain access to a view they do not actually have access to. WRONG! pyramid_jwt checks the signature of all JWT tokens as part of the decode process, if it notices that the signature of the token is not as expected, it means either the application has been setup correctly with the wrong private key, OR an attacker has tried to manipulate the token.

The major security concern when working with JWT tokens is where to store the token itself: While pyramid_jwt is able to detect tampered tokens, nothing can be done if the actual valid token leaks. Any user with a valid token will be correctly authenticated within your app. Storing the token securely is outside the scope of this library.

When using JWT within a cookie, the browser (or tool consuming the cookie) is responsible for storing it, but pyramid_jwt does set the http_only flag on all cookies, so javascript running on the page cannot access these cookies, which helps mitigate XSS attacks. It's still mentioning that the tokens are still visible through the browser's debugging/inspection tools.

Securing views with JWT's

In the example posted above we creating an "admin" role that we gave ALL_PERMISSIONS access in our ACL, so any user with this role could access any view e.g.:

@view_config(route_name='view_a', request_method='GET',
             permission="admin", renderer='json')
def view_a(request):
    return

@view_config(route_name='view_b', request_method='GET',
             permission="cpanel", renderer='json')
def view_b(request):
    return

This user would be able to access both of these views, however any user with the "reports" permission would not be able to access any of these views, they could only access permissions with "reports". Obviously in our use case, one user had both "admin" and "reports" permissions, so they would be able to access any view regardless.

Comments
  • Access & verify token sent in the header

    Access & verify token sent in the header

    I have setup my pyramid app such as:

    # Enable JWT - JSON Web Token based authentication
    config.set_authorization_policy(ACLAuthorizationPolicy())
    config.include('pyramid_jwt')
    config.set_jwt_authentication_policy('secret200', http_header='Bearer')
    
    # view code:
    @view_config(route_name='get_customer_name', request_method='POST', 
    	renderer='json_custom')
    def get_customer_name(request):
    	print (request)
    

    My frontend application send a JWT in the header, see the results of print (request) below:

    '''
    Accept: application/json, text/plain, */*
    Accept-Encoding: gzip, deflate
    Accept-Language: en-GB,en-US;q=0.8,en;q=0.6
    Authorization: Bearer "exJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJ0ZXN0MiI6Ikx1a2UgQ3Jvb2tzVEVTVDIiLCJpYXQiOjE1MDA0NTM5ODIsInN1YiI6eyJzdG9ja19lbnF1aXJ5X3Blcm0iOnRydWUsIm9yZGVyX2VudHJ5X3Blcm0iOnRydWUsInVzZXJpZCI6NCwidXNlcl9uYW1lIjoibHVrZSIsImFjY291bnRfZW5xdWlyeVwZXJtIjp0cnVlLCJzb2xlbnRfc3RhZmYiOnRydWV9fQ.UwQD6709-4WAidWffhRwaFIBOnXircfL6PC1wg-vpYUJtnojovP_X4QzP6mQDVR4o42vx8FyFpEGh49YJBhteg"
    Connection: keep-alive
    Content-Length: 21
    Content-Type: text/plain
    Host: 0.0.0.0:6543
    Origin: http://localhost:3000
    Referer: http://localhost:3000/order_entry
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/56.0.2924.76 Chrome/56.0.2924.76 Safari/537.36
    
    {"customerid":"7"}
    '''
    

    You can see that in the header is my JWT token (Authorization: Bearer ).

    My question is, in my view code, how do I now access this JWT, I want to verify the signature with the secret key (e.g. secret200) and test the token has not expired, before returning information back to the frontend. I could easily do this manually with the pyJWT library, but I am assuming this plugin is designed to take care of this, could you provide some help/assistance in configuration? Thanks.

    opened by crooksey 20
  • JWT tokens inside Cookies

    JWT tokens inside Cookies

    These changes adds support for using JWT token on HttpOnly cookies.

    Key benefits are:

    • Cookies are usually dealt with automatically by browsers.
    • Allow sliding sessions
    • Still stateless: does not use server-side sessions
    enhancement 
    opened by phrfpeixoto 11
  • Invalid json_encoder on master branch

    Invalid json_encoder on master branch

    Hi there,

    The master branch is failing tests due to the incorrectly set json_encoder default. PR #12 introduced Pyramid's json_renderer_factory as a default value for the json_encoder parameter to be used by jwt.

    json_renderer_factory is not an encoder. It's a factory pattern, that creates a Pyramid Renderer. These are completely different objects, that have completely different interfaces. The renderer itself has it's own JSON serializer and extends on it using Pyramid's adapters.

    The renderer generated by this factory is not a subclass of JSONEncoder

    I guess the goal here would be to benefit from any configured JSON renderer adapter. If so, we should properly generate a default function to be used by the JSONEncoder, like json_renderer_factory does on-demand.

    opened by phrfpeixoto 10
  • Error decoding a token with audience claim

    Error decoding a token with audience claim

    I'm getting a "Invalid audience" error from the pyramid_jwt lib. There is an audience section in the token:

    {
    "nbf": 1520083317,
    "exp": 1520086917,
    "iss": "https://demo.identityserver.io",
    "aud": [
    "https://demo.identityserver.io/resources",
    "api"
    ],
    "client_id": "client",
    "scope": [
    "api"
    ]
    }
    

    Can I somehow pass an audience param down to the decode method?

    opened by einarjohnson 8
  • Is there any plan to add graphene/graghql support to pyramid_jwt?

    Is there any plan to add graphene/graghql support to pyramid_jwt?

    @wichert

    Is there any plan to add graphene/graghql support to pyramid_jwt?

    There is already Django and Flask version of such application, that support both graphene and jwt, but nothing in Pyramid yet.

    Thanks

    question wontfix 
    opened by sydoluciani 4
  • Non-standard 'Authorization' schema?

    Non-standard 'Authorization' schema?

    The JWT docs state:

    Whenever the user wants to access a protected route or resource, it should send the JWT, typically in the Authorization header using the Bearer schema.

    We default to JWT as the schema here. Is this a standard somewhere else?

    opened by bmcorser 4
  • Expired token allowed to access views.

    Expired token allowed to access views.

    I may be having a blank moment here, but I thought if a token was invalid/expired, it would not allow the request to retrieve view data that was protected with a permissions= flag.

    For example:

    @view_config(route_name='add_product', request_method='POST',
                 renderer='json', permission="website_staff")
    

    I can see that my console is logging an expired token, judging by

    https://github.com/wichert/pyramid_jwt/blob/3390d98d361568d6a2e04f5c786b6ec8ddb84a2d/src/pyramid_jwt/policy.py#L78

    That pyramid_jwt is returning {} (have tested this locally and this is the case) yet the request is still able to access a protected view. Shouldn't this throw a forbidden error?

    For example:

    import pyramid.httpexceptions as exc
    ...
    raise exc.HTTPForbidden()
    

    However, if I try and access a protected view, with no token, a 403 does get returned, so I am unsure why when returning {} after warning that the token is expired, is still returning data.

    question 
    opened by crooksey 3
  • Wrong prefix for algorithm check when public key is present

    Wrong prefix for algorithm check when public key is present

    hey,

    took me a while to figure out but you're checking the wrong prefix when using an asymetric ES algorithm. According to PyJWT documentation, the prefix is ES and not EC. For me, this resulted in not loading the public key (being None).

    Should be an easy fix for you. Thx

    opened by m1schka 3
  • Log string formatted

    Log string formatted

    The params of log string in src/pyramid_jwt/policy.py line 77 are not formatted. It shows up as following in my logfile:

    Invalid JWT token from %s: %s

    I am using python version 3.6.9. Is it because of the way I initialize the logger or could it be a pyramid_jwt issue?

    question 
    opened by TomOudeNijhuis 2
  • Add option to define custom json_encoder

    Add option to define custom json_encoder

    New option to specify a custom json encoder. Can be useful when the claim value or principal could not be encoded by the default json encoder (example : uuid)

    opened by julienmeyer 2
  • Support for additional claims in create_jwt_token method

    Support for additional claims in create_jwt_token method

    First, thanks for publishing this package. Like you, I was using pyramid_jwtauth. This is a much cleaner implementation!

    I need to include additional claims (e.g. group, role) in the payload, which ideally I'd like to be able to include like...

    token = request.create_jwt_token(claims)
    

    ...instead of having to define an additional method...

    import jwt
    from pyramid.interfaces import IAuthenticationPolicy
    
    def encode_auth_token(request, claims):
        policy = request.registry.queryUtility(IAuthenticationPolicy)
        return jwt.encode(claims, policy.private_key, algorithm=policy.algorithm)
    
    token = encode_auth_token(request, claims)
    

    (Of course, this doesn't include any default claims like your current create_jwt_token method.)

    I'd suggest that additional claims are common enough to warrant including in the convenience method attached to the request object. If I submitted a PR, would you rather see the inclusion of additional claims as an update to the create_jwt_token method or as a new method altogether (e.g. create_custom_jwt_token)? If an update to create_jwt_token is preferable, could it be a breaking change like...

    token = request.create_jwt_token(claims)
    

    ...or should it be a non-breaking (but more confusing) change like...

    token = request.create_jwt_token(user_id, claims)
    

    ?

    Thanks.

    opened by bfin 2
  • docs: fix simple typo, assymetric -> asymmetric

    docs: fix simple typo, assymetric -> asymmetric

    There is a small typo in README.rst.

    Should read asymmetric rather than assymetric.

    Semi-automated pull request generated by https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

    opened by timgates42 0
  • Bump waitress from 1.4.3 to 2.1.1

    Bump waitress from 1.4.3 to 2.1.1

    Bumps waitress from 1.4.3 to 2.1.1.

    Changelog

    Sourced from waitress's changelog.

    2.1.1

    Security Bugfix

    
    - Waitress now validates that chunked encoding extensions are valid, and don't
      contain invalid characters that are not allowed. They are still skipped/not
      processed, but if they contain invalid data we no longer continue in and
      return a 400 Bad Request. This stops potential HTTP desync/HTTP request
      smuggling. Thanks to Zhang Zeyu for reporting this issue. See
      https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36
    
    • Waitress now validates that the chunk length is only valid hex digits when parsing chunked encoding, and values such as 0x01 and +01 are no longer supported. This stops potential HTTP desync/HTTP request smuggling. Thanks to Zhang Zeyu for reporting this issue. See https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36

    • Waitress now validates that the Content-Length sent by a remote contains only digits in accordance with RFC7230 and will return a 400 Bad Request when the Content-Length header contains invalid data, such as +10 which would previously get parsed as 10 and accepted. This stops potential HTTP desync/HTTP request smuggling Thanks to Zhang Zeyu for reporting this issue. See https://github.com/Pylons/waitress/security/advisories/GHSA-4f7p-27jc-3c36

    2.1.0

    Python Version Support

    • Python 3.6 is no longer supported by Waitress

    • Python 3.10 is fully supported by Waitress

    Bugfix

    
    - ``wsgi.file_wrapper`` now sets the ``seekable``, ``seek``, and ``tell``
      attributes from the underlying file if the underlying file is seekable. This
      allows WSGI middleware to implement things like range requests for example
    

    See Pylons/waitress#359 and Pylons/waitress#363

    • In Python 3 OSError is no longer subscriptable, this caused failures on Windows attempting to loop to find an socket that would work for use in the trigger.

    </tr></table>

    ... (truncated)

    Commits
    • 9e0b8c8 Merge pull request from GHSA-4f7p-27jc-3c36
    • b28c9e8 Prep for 2.1.1
    • bd22869 Remove extraneous calls to .strip() in Chunked Encoding
    • d9bdfa0 Validate chunk size in Chunked Encoding are HEXDIG
    • d032a66 Error when receiving back Chunk Extension
    • 884bed1 Update tests to remove invalid chunked encoding chunk-size
    • 1f6059f Be more strict in parsing Content-Length
    • e75b0d9 Add new regular expressions for Chunked Encoding
    • 22c0394 Merge pull request #367 from Pylons/fixup/collect-wasyncore-tests
    • dc15d9f Make sure to collect all wasyncore tests
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Return JWT in response body and as cookie

    Return JWT in response body and as cookie

    I have a legacy api which uses Pyramid remember/forget with auth_tkt. I now need to also use this api to authenticate users using JWT. Thanks to your module, I have converted the legacy app to use JWT with cookies and it works great. However, the new app requires me to extract the JWT somehow and pass it to a subsequent auth system. I cannot access the JWT on the client from the cookie because it is secure. So I'm wondering if it's possible to return the JWT in the response body (as well as in the cookie). Is that possible?

    opened by mattbodman 0
  • Authentication and authorization policies have been deprecated in favor of security policies.

    Authentication and authorization policies have been deprecated in favor of security policies.

    Getting these deprecation warnings in Pyramid 2.0. Are there any fixes please or advice on how best to resolve this?

    DeprecationWarning: Authentication and authorization policies have been deprecated 
    in favor of security policies. See "Upgrading Authentication/Authorization" in "What's New in Pyramid 2.0"
    of the documentation for more information.
    

    thanks

    opened by bachirelkhoury 0
  • Bump py from 1.4.31 to 1.10.0

    Bump py from 1.4.31 to 1.10.0

    Bumps py from 1.4.31 to 1.10.0.

    Changelog

    Sourced from py's changelog.

    1.10.0 (2020-12-12)

    • Fix a regular expression DoS vulnerability in the py.path.svnwc SVN blame functionality (CVE-2020-29651)
    • Update vendored apipkg: 1.4 => 1.5
    • Update vendored iniconfig: 1.0.0 => 1.1.1

    1.9.0 (2020-06-24)

    • Add type annotation stubs for the following modules:

      • py.error
      • py.iniconfig
      • py.path (not including SVN paths)
      • py.io
      • py.xml

      There are no plans to type other modules at this time.

      The type annotations are provided in external .pyi files, not inline in the code, and may therefore contain small errors or omissions. If you use py in conjunction with a type checker, and encounter any type errors you believe should be accepted, please report it in an issue.

    1.8.2 (2020-06-15)

    • On Windows, py.path.locals which differ only in case now have the same Python hash value. Previously, such paths were considered equal but had different hashes, which is not allowed and breaks the assumptions made by dicts, sets and other users of hashes.

    1.8.1 (2019-12-27)

    • Handle FileNotFoundError when trying to import pathlib in path.common on Python 3.4 (#207).

    • py.path.local.samefile now works correctly in Python 3 on Windows when dealing with symlinks.

    1.8.0 (2019-02-21)

    • add "importlib" pyimport mode for python3.5+, allowing unimportable test suites to contain identically named modules.

    • fix LocalPath.as_cwd() not calling os.chdir() with None, when being invoked from a non-existing directory.

    ... (truncated)

    Commits
    • e5ff378 Update CHANGELOG for 1.10.0
    • 94cf44f Update vendored libs
    • 5e8ded5 testing: comment out an assert which fails on Python 3.9 for now
    • afdffcc Rename HOWTORELEASE.rst to RELEASING.rst
    • 2de53a6 Merge pull request #266 from nicoddemus/gh-actions
    • fa1b32e Merge pull request #264 from hugovk/patch-2
    • 887d6b8 Skip test_samefile_symlink on pypy3 on Windows
    • e94e670 Fix test_comments() in test_source
    • fef9a32 Adapt test
    • 4a694b0 Add GitHub Actions badge to README
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Support to multiple public_keys

    Support to multiple public_keys

    Hello,

    In my use case an application will receive requests from two different identity providers which have their own private_key, is there any resource for dealing with multiple public_key implemented already, or should I extend to cover this use case?

    opened by PatrickSampaioUSP 0
Releases(1.6.1)
Owner
Wichert Akkerman
Wichert Akkerman
Python library for generating a Mastercard API compliant OAuth signature.

oauth1-signer-python Table of Contents Overview Compatibility References Usage Prerequisites Adding the Library to Your Project Importing the Code Loa

23 Aug 01, 2022
A flask extension for managing permissions and scopes

Flask-Pundit A simple flask extension to organize resource authorization and scoping. This extension is heavily inspired by the ruby Pundit library. I

Anurag Chaudhury 49 Dec 23, 2022
Mock authentication API that acceccpts email and password and returns authentication result.

Mock authentication API that acceccpts email and password and returns authentication result.

Herman Shpryhau 1 Feb 11, 2022
Official implementation of the AAAI 2022 paper "Learning Token-based Representation for Image Retrieval"

Token: Token-based Representation for Image Retrieval PyTorch training code for Token-based Representation for Image Retrieval. We propose a joint loc

Hui Wu 42 Dec 06, 2022
A generic, spec-compliant, thorough implementation of the OAuth request-signing logic

OAuthLib - Python Framework for OAuth1 & OAuth2 *A generic, spec-compliant, thorough implementation of the OAuth request-signing logic for Python 3.5+

OAuthlib 2.5k Jan 01, 2023
A module making it easier to manage Discord oAuth with Quart

quart_discord A module making it easier to manage Discord oAuth with Quart Install pip install git+https://github.com/xelA/ 5 Oct 27, 2022

An introduction of Markov decision process (MDP) and two algorithms that solve MDPs (value iteration, policy iteration) along with their Python implementations.

Markov Decision Process A Markov decision process (MDP), by definition, is a sequential decision problem for a fully observable, stochastic environmen

Yu Shen 31 Dec 30, 2022
Authentication Module for django rest auth

django-rest-knox Authentication Module for django rest auth Knox provides easy to use authentication for Django REST Framework The aim is to allow for

James McMahon 878 Jan 04, 2023
Basic auth for Django.

Basic auth for Django.

bichanna 2 Mar 25, 2022
Alisue 299 Dec 06, 2022
A Python tool to generate and refresh Amazon access tokens.

amazon_auth A Python tool to generate and refresh Amazon access tokens. Description This tool generates and outputs Amazon access and refresh tokens f

15 Nov 21, 2022
This project is an open-source project which I made due to sharing my experience around the Python programming language.

django-tutorial This project is an open-source project which I made due to sharing my experience around the Django framework. What is Django? Django i

MohammadMasoumi 6 May 12, 2022
A host-guest based app in which host can CREATE the room. and guest can join room with room code and vote for song to skip. User is authenticated using Spotify API

A host-guest based app in which host can CREATE the room. and guest can join room with room code and vote for song to skip. User is authenticated using Spotify API

Aman Raj 5 May 10, 2022
Ready to use and customizable Authentications and Authorisation management for FastAPI ⚡

AuthenticationX 💫 Ready-to-use and customizable Authentications and Oauth2 management for FastAPI ⚡ Source Code: https://github.com/yezz123/AuthX Doc

Yasser Tahiri 404 Dec 27, 2022
API-key based security utilities for FastAPI, focused on simplicity of use

FastAPI simple security API key based security package for FastAPI, focused on simplicity of use: Full functionality out of the box, no configuration

Tolki 154 Jan 03, 2023
FastAPI Simple authentication & Login API using GraphQL and JWT

JeffQL A Simple FastAPI authentication & Login API using GraphQL and JWT. I choose this Name JeffQL cause i have a Low level Friend with a Nickname Je

Yasser Tahiri 26 Nov 24, 2022
Simple Login - Login Extension for Flask - maintainer @cuducos

Login Extension for Flask The simplest way to add login to flask! How it works First, install it from PyPI: $ pip install flask_simplelogin Then, use

Flask Extensions 181 Jan 01, 2023
PetitPotam - Coerce NTLM authentication from Windows hosts

Python implementation for PetitPotam

ollypwn 137 Dec 28, 2022
Implementation of Supervised Contrastive Learning with AMP, EMA, SWA, and many other tricks

SupCon-Framework The repo is an implementation of Supervised Contrastive Learning. It's based on another implementation, but with several differencies

Ivan Panshin 132 Dec 14, 2022
Automatic login utility of free Wi-Fi captive portals

wicafe Automatic login utility of free Wi-Fi captive portals Disclaimer: read and grant the Terms of Service of Wi-Fi services before using it! This u

Takumi Sueda 8 May 31, 2022