Simple integration between FastAPI and cloud authentication services (AWS Cognito, Auth0, Firebase Authentication).

Overview

FastAPI Cloud Auth

Tests codecov PyPI version

fastapi-cloudauth standardizes and simplifies the integration between FastAPI and cloud authentication services (AWS Cognito, Auth0, Firebase Authentication).

Features

  • Verify access/id token: standard JWT validation (signature, expiration), token audience claims and etc.
  • Verify permissions based on scope (or groups) within access token and Extract user info
  • Get the detail of login user info (name, email, etc.) within ID token
  • Dependency injection for verification/getting user, powered by FastAPI
  • Support for:

Requirements

Python 3.6+

Install

$ pip install fastapi-cloudauth

Example (AWS Cognito)

Pre-requirement

  • Check region, userPoolID and AppClientID of AWS Cognito that you manage to
  • Create a user assigned read:users permission in AWS Cognito
  • Get Access/ID token for the created user

NOTE: access token is valid for verification, scope-based authentication and getting user info (optional). ID token is valid for verification and getting full user info from claims.

Create it

Create a file main.py with:

import os
from pydantic import BaseModel
from fastapi import FastAPI, Depends
from fastapi_cloudauth.cognito import Cognito, CognitoCurrentUser, CognitoClaims

app = FastAPI()
auth = Cognito(
    region=os.environ["REGION"], 
    userPoolId=os.environ["USERPOOLID"],
    client_id=os.environ["APPCLIENTID"]
)

@app.get("/", dependencies=[Depends(auth.scope(["read:users"]))])
def secure():
    # access token is valid
    return "Hello"


class AccessUser(BaseModel):
    sub: str


@app.get("/access/")
def secure_access(current_user: AccessUser = Depends(auth.claim(AccessUser))):
    # access token is valid and getting user info from access token
    return f"Hello", {current_user.sub}


get_current_user = CognitoCurrentUser(
    region=os.environ["REGION"], 
    userPoolId=os.environ["USERPOOLID"],
    client_id=os.environ["APPCLIENTID"]
)


@app.get("/user/")
def secure_user(current_user: CognitoClaims = Depends(get_current_user)):
    # ID token is valid and getting user info from ID token
    return f"Hello, {current_user.username}"

Run the server with:

$ uvicorn main:app

INFO:     Started server process [15332]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

Interactive API Doc

Go to http://127.0.0.1:8000/docs.

You will see the automatic interactive API documentation (provided by Swagger UI).

Authorize 🔓 button can be available at the endpoints injected dependency.

You can supply a token and try the endpoint interactively.

Swagger UI

Example (Auth0)

Pre-requirement

  • Check domain, customAPI (Audience) and ClientID of Auth0 that you manage to
  • Create a user assigned read:users permission in Auth0
  • Get Access/ID token for the created user

Create it

Create a file main.py with:

import os
from pydantic import BaseModel
from fastapi import FastAPI, Depends
from fastapi_cloudauth.auth0 import Auth0, Auth0CurrentUser, Auth0Claims

app = FastAPI()

auth = Auth0(domain=os.environ["DOMAIN"], customAPI=os.environ["CUSTOMAPI"])


@app.get("/", dependencies=[Depends(auth.scope(["read:users"]))])
def secure():
    # access token is valid
    return "Hello"


class AccessUser(BaseModel):
    sub: str


@app.get("/access/")
def secure_access(current_user: AccessUser = Depends(auth.claim(AccessUser))):
    # access token is valid and getting user info from access token
    return f"Hello", {current_user.sub}


get_current_user = Auth0CurrentUser(
    domain=os.environ["DOMAIN"],
    client_id=os.environ["CLIENTID"]
)


@app.get("/user/")
def secure_user(current_user: Auth0Claims = Depends(get_current_user)):
    # ID token is valid and getting user info from ID token
    return f"Hello, {current_user.username}"

Try to run the server and see interactive UI in the same way.

Example (Firebase Authentication)

Pre-requirement

  • Create a user in Firebase Authentication and get project ID
  • Get ID token for the created user

Create it

Create a file main.py with:

from fastapi import FastAPI, Depends
from fastapi_cloudauth.firebase import FirebaseCurrentUser, FirebaseClaims

app = FastAPI()

get_current_user = FirebaseCurrentUser(
    project_id=os.environ["PROJECT_ID"]
)


@app.get("/user/")
def secure_user(current_user: FirebaseClaims = Depends(get_current_user)):
    # ID token is valid and getting user info from ID token
    return f"Hello, {current_user.user_id}"

Try to run the server and see interactive UI in the same way.

Additional User Information

We can get values for the current user from access/ID token by writing a few lines.

Custom Claims

For Auth0, the ID token contains extra values as follows (Ref at Auth0 official doc):

{
  "iss": "http://YOUR_DOMAIN/",
  "sub": "auth0|123456",
  "aud": "YOUR_CLIENT_ID",
  "exp": 1311281970,
  "iat": 1311280970,
  "name": "Jane Doe",
  "given_name": "Jane",
  "family_name": "Doe",
  "gender": "female",
  "birthdate": "0000-10-31",
  "email": "[email protected]",
  "picture": "http://example.com/janedoe/me.jpg"
}

By default, Auth0CurrentUser gives pydantic.BaseModel object, which has username (name) and email fields.

Here is sample code for extracting extra user information (adding user_id) from ID token:

from pydantic import Field
from fastapi_cloudauth.auth0 import Auth0Claims  # base current user info model (inheriting `pydantic`).

# extend current user info model by `pydantic`.
class CustomAuth0Claims(Auth0Claims):
    user_id: str = Field(alias="sub")

get_current_user = Auth0CurrentUser(domain=DOMAIN, client_id=CLIENTID)
get_current_user.user_info = CustomAuth0Claims  # override user info model with a custom one.

Or, we can also set new custom claims as follows:

get_user_detail = get_current_user.claim(CustomAuth0Claims)

@app.get("/new/")
async def detail(user: CustomAuth0Claims = Depends(get_user_detail)):
    return f"Hello, {user.user_id}"

Raw payload

If you doesn't require pydantic data serialization (validation), FastAPI-CloudAuth has a option to extract raw payload.

All you need is:

get_raw_info = get_current_user.claim(None)

@app.get("/new/")
async def raw_detail(user = Depends(get_raw_info)):
    # user has all items (ex. iss, sub, aud, exp, ... it depends on passed token) 
    return f"Hello, {user.get('sub')}"

Additional scopes

Advanced user-SCOPE verification to protect your API.

Supports:

  • all (default): required all scopes you set
  • any: At least one of the configured scopes is required

Use as (auth is this instanse and app is fastapi.FastAPI instanse):

from fastapi import Depends
from fastapi_cloudauth import Operator

@app.get("/", dependencies=[Depends(auth.scope(["allowned", "scopes"]))])
def api_all_scope():
    return "user has 'allowned' and 'scopes' scopes"

@app.get("/", dependencies=[Depends(auth.scope(["allowned", "scopes"], op=Operator._any))])
def api_any_scope():
    return "user has at least one of scopes (allowned, scopes)"

Development - Contributing

Please read the CONTRIBUTING how to setup development environment and testing.

Comments
  • TypeError: cannot pickle '_cffi_backend.FFI' object

    TypeError: cannot pickle '_cffi_backend.FFI' object

    Using a straight copy-paste of your example application, I get this pickle error.

    Traceback (most recent call last):
      File "/Users/scott/.local/bin/uvicorn", line 10, in <module>
        sys.exit(main())
      File "/Users/scott/.local/lib/python3.8/site-packages/click/core.py", line 829, in __call__
        return self.main(*args, **kwargs)
      File "/Users/scott/.local/lib/python3.8/site-packages/click/core.py", line 782, in main
        rv = self.invoke(ctx)
      File "/Users/scott/.local/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/Users/scott/.local/lib/python3.8/site-packages/click/core.py", line 610, in invoke
        return callback(*args, **kwargs)
      File "/Users/scott/.local/lib/python3.8/site-packages/uvicorn/main.py", line 355, in main
        run(**kwargs)
      File "/Users/scott/.local/lib/python3.8/site-packages/uvicorn/main.py", line 379, in run
        server.run()
      File "/Users/scott/.local/lib/python3.8/site-packages/uvicorn/main.py", line 407, in run
        loop.run_until_complete(self.serve(sockets=sockets))
      File "uvloop/loop.pyx", line 1456, in uvloop.loop.Loop.run_until_complete
      File "/Users/scott/.local/lib/python3.8/site-packages/uvicorn/main.py", line 414, in serve
        config.load()
      File "/Users/scott/.local/lib/python3.8/site-packages/uvicorn/config.py", line 300, in load
        self.loaded_app = import_from_string(self.app)
      File "/Users/scott/.local/lib/python3.8/site-packages/uvicorn/importer.py", line 20, in import_from_string
        module = importlib.import_module(module_str)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/importlib/__init__.py", line 127, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
      File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
      File "<frozen importlib._bootstrap>", line 991, in _find_and_load
      File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
      File "<frozen importlib._bootstrap_external>", line 783, in exec_module
      File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
      File "./main.py", line 12, in <module>
        @app.get("/", dependencies=[Depends(auth.scope("read:users"))])
      File "/Users/scott/.local/lib/python3.8/site-packages/fastapi_cloudauth/base.py", line 83, in scope
        obj = deepcopy(self)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 172, in deepcopy
        y = _reconstruct(x, memo, *rv)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 270, in _reconstruct
        state = deepcopy(state, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 146, in deepcopy
        y = copier(x, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 230, in _deepcopy_dict
        y[deepcopy(key, memo)] = deepcopy(value, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 146, in deepcopy
        y = copier(x, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 230, in _deepcopy_dict
        y[deepcopy(key, memo)] = deepcopy(value, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 172, in deepcopy
        y = _reconstruct(x, memo, *rv)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 270, in _reconstruct
        state = deepcopy(state, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 146, in deepcopy
        y = copier(x, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 230, in _deepcopy_dict
        y[deepcopy(key, memo)] = deepcopy(value, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 172, in deepcopy
        y = _reconstruct(x, memo, *rv)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 270, in _reconstruct
        state = deepcopy(state, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 146, in deepcopy
        y = copier(x, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 230, in _deepcopy_dict
        y[deepcopy(key, memo)] = deepcopy(value, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 172, in deepcopy
        y = _reconstruct(x, memo, *rv)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 270, in _reconstruct
        state = deepcopy(state, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 146, in deepcopy
        y = copier(x, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 230, in _deepcopy_dict
        y[deepcopy(key, memo)] = deepcopy(value, memo)
      File "/Users/scott/.pyenv/versions/3.8.3/lib/python3.8/copy.py", line 161, in deepcopy
        rv = reductor(4)
    TypeError: cannot pickle '_cffi_backend.FFI' object
    
    opened by scott2b 8
  • How to inject auth globally and then use .scope?

    How to inject auth globally and then use .scope?

    i have this code

    async def init_auth(app: FastAPI) -> None:
        logger.info("Auth: Configuring connection to {0}", repr(AUTH0_DOMAIN))
        app.state.auth0_client = Auth0(domain=AUTH0_DOMAIN)
        logger.info("Auth: Connection configured")
    
    
    def _get_client(request: Request) -> Auth0:
        return request.app.state.auth0_client
    
    
    def get_auth() -> Callable:
        return _get_client
    

    init_auth is triggered on app.add_event_handler("startup", init_auth(application))

    then this code does work

    @router.get("/something",
                response_model=Any,
                dependencies=[
                    Depends(get_auth)
                ]
                )
    async def get_something(
            request: Request
    ):
    return []
    

    i would like to use auth.scope("read:something") with Depends but i can't seem to make it work

    def get_auth_scoped(
            *,
            scope_name: str,
            client: Auth0 = Depends(get_auth)
    ) -> Callable:
        return client.scope(scope_name=scope_name)
    

    and

    @router.get("/something",
                response_model=Any,
                dependencies=[
                    Depends(get_auth_scoped(scope_name="read:something"))
                ]
                )
    async def get_something(
            request: Request
    ):
    return []
    

    it results in a AttributeError: 'Depends' object has no attribute 'scope'

    what am i missing here? please help?

    opened by spawn-guy 7
  • JWKError

    JWKError

    Hi, I am trying to make it work with Firebase. I am using exaclty the same code you have in the examples

    import os
    from fastapi import FastAPI, Depends
    from fastapi_cloudauth.firebase import FirebaseCurrentUser, FirebaseClaims
    
    app = FastAPI()
    
    get_current_user = FirebaseCurrentUser(
        project_id="my-project-id"
    )
    
    
    @app.get("/user/")
    def secure_user(current_user: FirebaseClaims = Depends(get_current_user)):
        # ID token is valid and getting user info from ID token
        return f"Hello, {current_user.user_id}"
    
    

    but I have the following error:

     File "./src/main.py", line 7, in <module>
        get_current_user = FirebaseCurrentUser(
      File "/home/elvis/Documents/dev-tools/API/env/lib/python3.9/site-packages/fastapi_cloudauth/firebase.py", line 28, in __init__
        jwks = JWKS.firebase(url)
      File "/home/elvis/Documents/dev-tools/API/env/lib/python3.9/site-packages/fastapi_cloudauth/verification.py", line 70, in firebase
        keys = {
      File "/home/elvis/Documents/dev-tools/API/env/lib/python3.9/site-packages/fastapi_cloudauth/verification.py", line 71, in <dictcomp>
        kid: jwk.construct(publickey, algorithm="RS256")
      File "/home/elvis/Documents/dev-tools/API/env/lib/python3.9/site-packages/jose/jwk.py", line 79, in construct
        return key_class(key_data, algorithm)
      File "/home/elvis/Documents/dev-tools/API/env/lib/python3.9/site-packages/jose/backends/rsa_backend.py", line 171, in __init__
        raise JWKError(e)
    jose.exceptions.JWKError: No PEM start marker "b'-----BEGIN PRIVATE KEY-----'" found
    

    Any idea?

    Thank you

    answered 
    opened by AlviseSembenico 5
  • auto_error setting not passed to HTTPBearer dependencies

    auto_error setting not passed to HTTPBearer dependencies

    Hi guys, thanks for writing this implementation!

    I'm currently trying to fit this one into our set-up but I run into an issue with auto_error=False setting not being respected by the dependency injections inside fastapi_cloudauth. Fastapi-cloudauth builds on the fastapi HTTPBearer dependency injection, which raises an HTTPException when the credentials are not found in the headers. To prevent this exception, it supports the auto_error=False option. We need this to support other authentication methods.

    Our authentication set-up is based on this medium article to combine multiple types of authentication. To make this work, the "auto_error=False" is essential, to make sure none of the authentication methods block each other. (see example implementation below)

    Proposed fix: In base.py, there are these dependency injections for HTTPBearer(), which currently don't pass the auto_error parameter: https://github.com/tokusumi/fastapi-cloudauth/blob/36d947fd3e638683fa1cb96e194bdaa054d92ee9/fastapi_cloudauth/base.py#L153 and https://github.com/tokusumi/fastapi-cloudauth/blob/36d947fd3e638683fa1cb96e194bdaa054d92ee9/fastapi_cloudauth/base.py#L192

    These dependencies do support the auto_error parameter, like: HTTPBearer(auto_error=self.auto_error). Possibly you'd want to set this up as a partial function in the constructor.


    For reference: example implementation This fails on an HTTPException from HTTPBearer when the OAuth headers are not passed - which unfortunately is the case when another authentication method is used..

    api_key_query_dependency = APIKeyQuery(name=settings.api_key_name, auto_error=False)
    api_key_header_dependency = APIKeyHeader(name=settings.api_key_name, auto_error=False)
    api_key_cookie_dependency = APIKeyCookie(name=settings.api_key_name, auto_error=False)
    cognito_auth_dependency = Cognito(region=settings.aws_region,
                                      userPoolId=settings.aws_cognito_user_pool_id,
                                      auto_error=False
                                      ).scope("users")
    
    
    async def get_authorization(
            api_key_query: str = Security(api_key_query_dependency),
            api_key_header: str = Security(api_key_header_dependency),
            api_key_cookie: str = Security(api_key_cookie_dependency),
            cognito_auth: str = Depends(cognito_auth_dependency),
    ) -> Security:
        if not cognito_auth \
                or api_key_query == settings.api_key \
                or api_key_header == settings.api_key \
                or api_key_cookie == settings.api_key:
            raise HTTPException(
                status_code=HTTP_403_FORBIDDEN, detail="Could not validate credentials"
            )
    
    opened by mjvdvlugt 5
  • Using auth0 id_token possibly insecure

    Using auth0 id_token possibly insecure

    First of all I have to admit that I don't fully grasp all the oauth2 and OIDC concepts, which is probably why I stumbled accross this project to begin with, not knowing how to implement all the details myself.

    Anyway, I've been reading auth0 documentation and this source code and I see it's possible to retrieve user email using Auth0Claims. But these claims are valid only if FastAPI gets an id_token as Bearer, which is recommended against in this article: https://auth0.com/blog/why-should-use-accesstokens-to-secure-an-api/ that mentions id_token is only meant for the client (which I understand is the frontend, not FastAPI).

    I would love to find a reason why the official recommendation is not valid in this project.

    In my fastapi API I need to know the user email for every request authorization. That's because I support multi-tenancy, where each user has CRUD access only to their own resources. I think this should be a fairly common scenario.. so I'm puzzled why there wouldn't be a straightforward way to do it.

    opened by dorinclisu 4
  • [Auth0] user_id from current user

    [Auth0] user_id from current user

    Hello,

    Is there a way to extract user_id from current user (Auth0) Auth0CurrentUser()? For example, if I use:

    get_current_user = Auth0CurrentUser("dev-some-domain.eu.auth0.com")
    
    @router.get("/")
    async def get_current_user(current_user=Depends(get_current_user)):
        return current_user
    

    as a result, I get a JSON object containing only name and email. Example:

    {
      "name": "[email protected]",
      "email": "[email protected]"
    }
    
    opened by goranvrbaski 3
  • Cannot access `/users/` using the AWS Cognito configuration

    Cannot access `/users/` using the AWS Cognito configuration

    Using the authorization modal (in the docs) ...

    • if I insert an id_token and attempt to access the /users/ endpoint a JWTClaimsError is caught (i.e. "No access_token provided to compare against at_hash claim.")
    • if I insert an access_token and attempt to access the /users/ endpoint the token_use claim is flagged (because it is equal to "id").

    What am I missing?

    opened by IshakAhmed 2
  • Auth0: get_current_user always gives 401

    Auth0: get_current_user always gives 401

    Hi there,

    This is almost certainly user error & not a bug, as I'm new to Auth0.

    In Auth0, I have configured an application (which is a VueJS client) set up as well as an API (my FastAPI back-end).

    I've managed to get authentication working using the example def main_endpoint_test(current_user: AccessUser = Depends(auth.claim(AccessUser))) - when I do this, I can get the user_id/sub, but I don't get the user email.

    I tried using the other approach shown in the example: def secure_user(current_user: Auth0Claims = Depends(get_current_user)):. When I use this, I always get a 401 response. I have initialised the get_current_user passing in the domain and client_id as shown in the example - because the domain is working fine in the simpler auth method, maybe my mistake is entering the wrong value for the client_id?

    What is the client ID value should I be setting here, is it my Auth0 Application's client ID (i.e. the one for the VueJS client)? Is it the custom API's ID (as far as I can tell, there is no field explicitly labelled "client ID" in auth0's APIs)?

    opened by lesiki 2
  • Support multiple scope

    Support multiple scope

    Support a part of #35, multiple scopes with all and any combinator. As:

    from fastapi_cloudauth import Operator
    
    @app.get("/access-all/")
    def secure_access_and(scope=Depends(auth.scope(["role_admin", "super_admin"]))):
        return f"Hello {scope}"
    
    @app.get("/access-any/")
    def secure_access_or(scope=Depends(auth.scope(["role_admin", "super_admin"], op=Operator._any))):
        return f"Hello {scope}"
    
    opened by tokusumi 2
  • Firebase x509 issue

    Firebase x509 issue

    python-jose doesn't support x509 certificates without the extra install option (anymore? I not quite sure if it was a silent breaking change). This breaks the FirebaseCurrentUser's JWKS generation because google gives x509 files for the public key.

    the recommended setup on python-jose is using cryptography as the background, setup as following

    pip install python-jose[cryptography]
    

    but is sort of a debate I guess (acknowledging the fact that cryptography requires building and is not a small dependency)

    At least it needs some documentation about it, so I would like to know whats good for this library.

    documentation 
    opened by yu-ichiro 2
  • Auth0 token

    Auth0 token

    First of all, thanks for your work, easy and clear to use 😄

    The issue I'm facing isn't related to repo itself, but on how to generate the Auth0 token to have all the needed information to use the methods properly.

    For some endpoints that I'm implementing I'll just need to check if the token has the required scopes and for some others I'll need to use: current_user: Auth0Claims = Depends(auth.get_current_user). However I can't find a way to request to Auth0 a token with all of this information: username and scopes. I don't know if I'm misunderstanding some information/concepts or what is going wrong...

    Would appreciate some information with the steps to follow. Thanks in advance!

    opened by guillemfrancisco 2
  • Feature: Add scopes required to the openapi docs

    Feature: Add scopes required to the openapi docs

    Hey guys so I wanted to request this feature that I think might be an interesting addition to the library that consists of adding on the Authorization documentation of each request under "HTTP Authorization Scheme" a new row called "Scopes Accepted/Required" where it would be a list of the scopes the backend requires for the request to be accepted.

    If you guys could point me to where I could start exploring this feature I might be able to develop my self and contribute but right now Im not sure where does the library define documentation sections.

    Here is a image of the place I refer to. image

    opened by DEADSEC-SECURITY 0
  • Having trouble figuring out

    Having trouble figuring out "next steps"

    I'm a "noob" where Cognito is concerned and could be missing something about accessing the example API's. I've got an AWS User Pool defined with a user created. How do I log that user in, or get a JWT Token to use to authorize the example API to access the endpoints? Thanks for your help.

    opened by writeson 1
  • Take lot of time to start a fastapi project

    Take lot of time to start a fastapi project

    image

    Here I have attached the Image, I have used a firebase example and just try to run on ubuntu 20. x LTS But it take long time to run while using on local machine (windows) it quickly run with in no time. is there any reason or is there any config where I am making mistake . same code run on local (windows machine ) fine but take long time on cloud which uses ubuntu

    opened by marxyes 0
  • [Cognito] App client_id is not validated for Cognito JWT (access_token)

    [Cognito] App client_id is not validated for Cognito JWT (access_token)

    I faced with an issue when using congito auth, app client_id is not validating during token verification. So you can path any ID and it will work.

    
    # pass some fake client_id
    auth = Cognito(region=aws_region, userPoolId=aws_cognito_userpool_id, client_id='foo-bar')
    
    # access_token - obtained from Cognito
    http_auth = HTTPAuthorizationCredentials(scheme='Bearer', credentials=access_token)
    
    await auth.verifier.verify_token(http_auth)
    True
    

    The problem is that jwt.decode (jose lib) doesn't expect client_id in token and since aud is not defined it skips validation.

    opened by tivaliy 0
  • Simple Auth0 authentication when using the doc or redoc page

    Simple Auth0 authentication when using the doc or redoc page

    When I use your Python package, things work really well, so many thanks for it. 😀

    However, there is one thing, where I ask myself, whether I can do much better here. When I try to reach my doc page, it looks like this:

    fastapi_doc

    When I click on the locking the top right, it looks like this

    fastapi_auth

    And after I enter the right token_id, I can work with the doc page as intended.

    However, getting the token_id is quite cumbersome, as it usually involves curl requests etc.

    It would be much nicer, if I am automatically logged in from Auth0, if I authenticated somewhere else in my browser. If I did not authenticate somewhere, then this here pops up

    auth0-login

    and after authenticating, I can work as intended. Is that possible?

    opened by junoriosity 0
Releases(v0.4.3)
  • v0.4.3(Jan 6, 2022)

    What's Changed

    • Disable at_hash verification (not used but could raise error in auth flow generating access and ID token simultaneously) by @sindrig in https://github.com/tokusumi/fastapi-cloudauth/pull/58

    New Contributors

    • @sindrig made their first contribution in https://github.com/tokusumi/fastapi-cloudauth/pull/58

    Full Changelog: https://github.com/tokusumi/fastapi-cloudauth/compare/v0.4.2...v0.4.3

    Source code(tar.gz)
    Source code(zip)
  • v0.4.2(Jan 2, 2022)

    What's Changed

    • Fix dependency for Firebase: auto-install cryptography with python-jose by @tokusumi in https://github.com/tokusumi/fastapi-cloudauth/pull/63
    • Add support python3.9 by @tokusumi in https://github.com/tokusumi/fastapi-cloudauth/pull/64

    Full Changelog: https://github.com/tokusumi/fastapi-cloudauth/compare/v0.4.1...v0.4.2

    Source code(tar.gz)
    Source code(zip)
  • v0.4.1(Jan 2, 2022)

    What's Changed

    • ✏️ Fix broken link to CONTRIBUTING and grammar in README by @discdiver in https://github.com/tokusumi/fastapi-cloudauth/pull/57
    • Store Firebase JWKS expiry and refresh keys when they expire by @jleclanche in #60 & @tokusumi in https://github.com/tokusumi/fastapi-cloudauth/pull/61
    • codecov-action v1 to v2 by @tokusumi in https://github.com/tokusumi/fastapi-cloudauth/pull/62

    New Contributors

    • @discdiver made their first contribution in https://github.com/tokusumi/fastapi-cloudauth/pull/57

    Full Changelog: https://github.com/tokusumi/fastapi-cloudauth/compare/v0.4.0...v0.4.1

    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jun 1, 2021)

    Security updates:

    • Add standard (and service specific) claims verification PR #45 by @tokusumi

    Features:

    • Support multiple scope validation PR #43 by @tokusumi

    Fixes:

    • Handle exceptions on malformed token PR #42 by @tokusumi & @jleclanche

    Internal:

    • Unification for test app instantiate PR #44 by @tokusumi
    Source code(tar.gz)
    Source code(zip)
  • v0.3.0(Feb 25, 2021)

    Add features:

    • Add extraction for access token (#31). Get user info from access token easily. related issue are #14, #21, #27.

    Breaking changes:

    • Auth0 default scope key turned to be "permissions" ("scope" was scope key before v0.2.0). please make sure RBAC setting is valid.
    • For development, environment variables, AUTH0_MGMT_CLIENTID and AUTH0_MGMT_CLIENT_KEY, will be required to auth0 testing.

    Docs:

    • Add development - contribution guide (#19)

    Bug fixes:

    • Various grammatical cleanups and a fix to the Auth0 example. (#15) by @justinrmiller
    • Handle no-token exception in module to respect auto_error setting (#24, #26) by @mjvdvlugt

    Internal changes:

    • Unify testcases (#17, #18)
    • Refactoring Base module (in #31)
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Dec 22, 2020)

    Add features

    • Firebase Authentication Support (Only ID token)

    Doc

    • Add Auth0 example
    • Add Firebase Authentication example
    • Add explanation how to define custom claims
    Source code(tar.gz)
    Source code(zip)
  • v0.1.3(Nov 1, 2020)

  • v0.1.2(Oct 7, 2020)

  • v0.1.1(Oct 7, 2020)

  • 0.1.0(Aug 2, 2020)

    • first release
    • Verify token (JWKS-based JSON Web Token)
    • Authenticate with scope (permissions)
    • Get user info in token
    • Dependency injection of the above
    • Use the above features in the interactive docs, else
    • Support for Auth0 and AWS Cognito
    Source code(tar.gz)
    Source code(zip)
Owner
tokusumi
tokusumi
A Python wrapper around the Soundcloud API

soundcloud-python A friendly wrapper around the Soundcloud API. Installation To install soundcloud-python, simply: pip install soundcloud Or if you'r

SoundCloud 83 Dec 12, 2022
Wrapper around the Mega API

python-mega Overview Wrapper around the Mega API. Based on the work of Julien Marchand. Installation Install using pip, including any optional package

Juan Riaza 104 Nov 26, 2022
Change the discord status throught websocket every 5 seconds with an insult

Discord status insult changer Change the discord status throught websocket every 5 seconds with an insult! - pip install httpx - put your tokens in "t

Ѵιcнч 10 Oct 27, 2022
TrollWare 🤡 is the most advanced Discord Malware & RAT

TrollWare 🤡 TrollWare is the most advanced Discord Malware, with a built-in RAT which can be controlled through a Discord Bot Pinned Note: Please giv

doop 74 Jun 09, 2022
Python CMR is an easy to use wrapper to the NASA EOSDIS Common Metadata Repository API.

This repository is a copy of jddeal/python_cmr which is no longer maintained. It has been copied here with the permission of the original author for t

NASA 9 Nov 16, 2022
A superb Telegram VoiceChat Player. Powered by FalconRoBo.

𝕱𝖆𝖑𝖈𝖔𝖓𝕸𝖚𝖘𝖎𝖈 A sᴜᴘᴇʀʙ Tᴇʟᴇɢʀᴀᴍ VᴏɪᴄᴇCʜᴀᴛ Pʟᴀʏᴇʀ, ᴍᴀᴅᴇ ᴜsɪɴɢ Lᴀᴛᴇsᴛ Pʏᴛʜᴏɴ ᴀɴᴅ Pʏʀᴏɢʀᴀᴍ. 𝑷𝒐𝒘𝒆𝒓𝒆𝒅 𝒃𝒚 𝑭𝒂𝒍𝒄𝒐𝒏𝑹𝒐𝑩𝒐 FalconMusic

FalconRoBo 2 Oct 21, 2022
THERE IS AN IMPOSTER AMONG US. VOTE HIM OUT BEFORE HE [ R E D A C T E D ].

🛡️ Guardian There is an impostor among us. Can you help us find out who it is? ⚙️ Installation and Usage Make sure to install Tesseract-OCR before ru

Catus Magnus 1 Jan 06, 2022
The Main Pythonic Version Of Twig Using Nextcord

The Main Pythonic Version Of Twig Using Nextcord

8 Mar 21, 2022
An API that allows you to get full information about TikTok videos

TikTok-API An API that allows you to get full information about TikTok videos without using any third party sources and only the TikTok API. ##API onl

FC 13 Dec 20, 2021
Lending-Club-Loans - Using TensorFlow to create an ANN model to predict whether people would charge off or pay back their loans.

Lending Club Loans: Brief Introduction LendingClub is a US peer-to-peer lending company, headquartered in San Francisco, California.[3] It was the fir

Ali Akram 1 Jan 03, 2022
Discord Panel is an AIO panel for Discord that aims to have all the needed tools related to user token interactions, as in nuking and also everything you could possibly need for raids

Discord Panel Discord Panel is an AIO panel for Discord that aims to have all the needed tools related to user token interactions, as in nuking and al

11 Mar 30, 2022
A Telegram Bot which notifies the user when a vaccine is available on CoWin Platform.

Cowin Vaccine Availability Notifier Telegram Bot A bot that notifies the available vaccines at given district in realtime. Introduction • Requirements

Arham Shah 7 Jul 31, 2021
Tiktok-bot - A Simple Tiktok bot With Python

Install the requirements pip install selenium pip install pyfiglet==0.7.5 How ca

Muchlis Faroqi 5 Aug 23, 2022
QuickStart specific rules for cfn-python-lint

AWS Quick Start cfn-lint rules This repo provides CloudFormation linting rules specific to AWS Quick Start guidelines, for more information see the Co

AWS Quick Start 12 Jul 30, 2022
Man-Userbot adalah userbot Telegram modular yang berjalan di Python3 dengan database sqlalchemy

Man-Userbot Telegram Man-Userbot adalah userbot Telegram modular yang berjalan di Python3 dengan database sqlalchemy. Berbasis Paperplane dan ProjectB

DzLyz 1 Feb 12, 2022
Primeira etapa do processo seletivo para a bolsa de migração de conteúdo de Design de Software.

- Este processo já foi concluído. Obrigado pelo seu interesse! Processo Seletivo para a bolsa de migração de conteúdo de Design de Software Primeirame

Toshi Kurauchi 1 Feb 21, 2022
A Telegram bot that can stream Telegram files to users over HTTP.

T.ME_FILE_TO_LINK Hi iam a file to link bot....best Bot telegram Telegram File To Link Generation Bot A Telegram bot that can stream Telegram files to

1 Oct 24, 2021
This is a very simple botnet with a CnC server, made by me. Feel free to change anything

This is a very simple botnet with a CnC server, made by me. Feel free to change anything

8 Nov 12, 2022
Códigos pela Força Bruta e Algoritmo Genético para o Problema da Mochila

O problema da mochila é um problema de optimização combinatória. O nome dá-se devido ao modelo de uma situação em que é necessário preencher uma mochi

Hemili Beatriz 1 Jan 08, 2022