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
Unauthenticated enumeration of services, roles, and users in an AWS account or in every AWS account in existence.

Quiet Riot ?? C'mon, Feel The Noise ?? An enumeration tool for scalable, unauthenticated validation of AWS principals; including AWS Acccount IDs, roo

Wes Ladd 89 Jan 5, 2023
Automatically compile an AWS Service Control Policy that ONLY allows AWS services that are compliant with your preferred compliance frameworks.

aws-allowlister Automatically compile an AWS Service Control Policy that ONLY allows AWS services that are compliant with your preferred compliance fr

Salesforce 189 Dec 8, 2022
Automated AWS account hardening with AWS Control Tower and AWS Step Functions

Automate activities in Control Tower provisioned AWS accounts Table of contents Introduction Architecture Prerequisites Tools and services Usage Clean

AWS Samples 20 Dec 7, 2022
Implement backup and recovery with AWS Backup across your AWS Organizations using a CI/CD pipeline (AWS CodePipeline).

Backup and Recovery with AWS Backup This repository provides you with a management and deployment solution for implementing Backup and Recovery with A

AWS Samples 8 Nov 22, 2022
AWS Blog post code for running feature-extraction on images using AWS Batch and Cloud Development Kit (CDK).

Batch processing with AWS Batch and CDK Welcome This repository demostrates provisioning the necessary infrastructure for running a job on AWS Batch u

AWS Samples 7 Oct 18, 2022
💻 A fully functional local AWS cloud stack. Develop and test your cloud & Serverless apps offline!

LocalStack - A fully functional local AWS cloud stack LocalStack provides an easy-to-use test/mocking framework for developing Cloud applications. Cur

LocalStack 45.3k Jan 2, 2023
A tool to build scripts to toggle between minimal & default services in Windows based on user defined lists.

A tool to build scripts to toggle between minimal & default services in Windows based on user defined lists.

AMIT 29 Jan 1, 2023
A solution designed to extract, transform and load Chicago crime data from an RDS instance to other services in AWS.

This project is intended to implement a solution designed to extract, transform and load Chicago crime data from an RDS instance to other services in AWS.

Yesaswi Avula 1 Feb 4, 2022
Lambda-function - Python codes that allow notification of changes made to some services using the AWS Lambda Function

AWS Lambda Function This repository contains python codes that allow notificatio

Elif Apaydın 3 Feb 11, 2022
A Bot to Upload files to Many Cloud services. Powered by Telethon.

oVo MultiUpload V1.0 ?? A Bot to Upload files to Many Cloud services. Powered by Telethon _ ?? Follow me and star this repo for more telegram bots. @H

null 32 Dec 30, 2022
AWS Auto Inventory allows you to quickly and easily generate inventory reports of your AWS resources.

Photo by Denny Müller on Unsplash AWS Automated Inventory ( aws-auto-inventory ) Automates creation of detailed inventories from AWS resources. Table

AWS Samples 123 Dec 26, 2022
A suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier

A suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier

Amazon Web Services - Labs 1.9k Jan 7, 2023
SSH-Restricted deploys an SSH compliance rule (AWS Config) with auto-remediation via AWS Lambda if SSH access is public.

SSH-Restricted SSH-Restricted deploys an SSH compliance rule with auto-remediation via AWS Lambda if SSH access is public. SSH-Auto-Restricted checks

Adrian Hornsby 30 Nov 8, 2022
aws-lambda-scheduler lets you call any existing AWS Lambda Function you have in a future time.

aws-lambda-scheduler aws-lambda-scheduler lets you call any existing AWS Lambda Function you have in the future. This functionality is achieved by dyn

Oğuzhan Yılmaz 57 Dec 17, 2022
POC de uma AWS lambda que executa a consulta de preços de criptomoedas, e é implantada na AWS usando Github actions.

Cryptocurrency Prices Overview Instalação Repositório Configuração CI/CD Roadmap Testes Overview A ideia deste projeto é aplicar o conteúdo estudado s

Gustavo Santos 3 Aug 31, 2022
Python + AWS Lambda Hands OnPython + AWS Lambda Hands On

Python + AWS Lambda Hands On Python Criada em 1990, por Guido Van Rossum. "Bala de prata" (quase). Muito utilizado em: Automatizações - Selenium, Beau

Marcelo Ortiz de Santana 8 Sep 9, 2022
Aws-lambda-requests-wrapper - Request/Response wrapper for AWS Lambda with API Gateway

AWS Lambda Requests Wrapper Request/Response wrapper for AWS Lambda with API Gat

null 1 May 20, 2022
AWS-serverless-starter - AWS Lambda serverless stack via Serverless framework

Serverless app via AWS Lambda, ApiGateway and Serverless framework Configuration

 Bəxtiyar 3 Feb 2, 2022