JWT Authentication with Blacksheep and Auth0 | Python.
Published: 2022-12-16 14:44:12

---
title: JWT Authentication with Blacksheep and Auth0 | Python.
published: true
date: 2022-12-13 15:46:56 UTC
tags: 
canonical_url: https://carlosmv.hashnode.dev/jwt-authentication-with-blacksheep-and-auth0-python
---

Blacksheep has built-in authentication and authorization support and allows us to integrate with services like Auth0, Azure Active Directory, Azure Active Directory B2C, or Okta.

For this tutorial, we will build an API with the Blacksheep framework with JWT authentication. In our API there will be a public endpoint and a private endpoint only for authorized users.

We are going to use the same example shown in the documentation, but instead, we are going to use Auth0. So, we need an [Auth0 account](https://auth0.com/).

### Prerequisites

- Basic Python knowledge

- How to create a basic web app with Blacksheep Framework

If you don't know how to create an app with Blacksheep, here is the [documentation](https://www.neoteroi.dev/blacksheep/getting-started/) explaining it.

### Auth0

According to its [documentation](https://auth0.com/docs/articles):

> Auth0 is an identity platform to add sophisticated authentication and authorization to your applications. Centralize and manage users from multiple identity providers and give them branded, seamless signup and login experiences. Finely control access with a degree of customization that can accommodate even the most complex security requirements. Easily deploy your implementation and monitor status and services.

### Create an Auth0 application

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1669516687780/saAOKZezT.png)

After we create an account, we click on "Sign Up".

After our account is created. We go to our Dashboard a click on "Create Application".

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1669514001875/4DG-q4cLO.png)

We select "Regular Web Applications". And then, choose Python.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1669514182680/9bxFqG9gM.png)

### .env file

```
AUTHORITY={DOMAIN}
AUDIENCE=https://{DOMAIN}/api/v2/
ISSUERS= https://{DOMAIN}

```

Then, we go to our app's settings copy the "Domain" and "Client ID" and paste them inside a `.env` file.

We will use the Client ID when we need to request the token.

### Setup

We create our virtual environment.

```
py -m venv venv
cd venv/Scripts
activate

```

Then, we install the packages we are going to use.

```
pip install uvicorn blacksheep[full] python-dotenv

```

When we import `blacksheep[full]` we are importing the necessary dependencies to use JWT Bearer authentication.

> "The authentication and authorization logic implemented for BlackSheep was packed and published into a dedicated library:`guardpost` [(in pypi](https://pypi.org/project/guardpost/))."

Blacksheep uses [GuarPost](https://github.com/Neoteroi/GuardPost) to handle authentication and authorization. It provides a basic framework to handle authentication and authorization for any kind of Python application.

### main.py

```
from blacksheep import Application
from blacksheep.server.authorization import auth
from guardpost.common import AuthenticatedRequirement, Policy

from blacksheep.server.authentication.jwt import JWTBearerAuthentication

from dotenv import load_dotenv
import os

load_dotenv()

app = Application()

app.use_authentication().add(
    JWTBearerAuthentication(
        authority=os.environ.get("AUTHORITY"),
        valid_audiences=[os.environ.get("AUDIENCE")],
        valid_issuers=[os.environ.get("ISSUERS")],
    )
)

authorization = app.use_authorization()

authorization += Policy("any_name", AuthenticatedRequirement())

get = app.router.get

@get("/")
def home():
    return "Hello, World"

@auth("any_name")
@get("/api/message")
def example():
    return "This is only for authenticated users"

```

We create an instance of `JWTBearerAuthentication` class and add the parameters: Authority, audiences, and issuers.

`JWTBearerAuthentication` is a child class of `AuthenticationHandler`, that can parse and verify JWT Bearer access tokens to identify users.

> Creates a new instance of JWTBearerAuthentication, which tries to obtains the identity of the user from the "Authorization" request header, handling JWT Bearer tokens. Only standard authorization headers starting with the `Bearer` string are handled.

`JWTBearerAuthentication` has more attributes, we can see them [here](https://github.com/Neoteroi/BlackSheep/blob/main/blacksheep/server/authentication/jwt.py).

When we start our server we will notice that we can't access the `api/message` endpoint. The server returns an "Unauthorized" status code.

### Getting a token

We need the following information from our Auth0 Dashboard: Client ID and Client Secret.

Using a web client, we make a POST request to the URL: `https://{your domain}.com/oauth/token`. And with the following body:

```
{"client_id":"CLIENT ID","client_secret":"CLIENT SECRET","audience":"https://{Your domain}.us.auth0.com/api/v2/","grant_type":"client_credentials"}

```

If the HTTP response is OK, we will receive a response body like this:

```
"access_token":"TOKEN","expires_in":86400,"token_type":"Bearer"}

```

Now, we make a GET request to our protected endpoint, but we add the "Bearer" authorization header and paste the token.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1670862175583/wVuH71Pv9.png)

### Conclusion

I liked the approach of Blacksheep, it is the first time I use an authentication service like Auth0. I think it offers something different from other frameworks. And it saves a lot of time. I still have to learn how to write a custom authentication handler, and probably write about it.

Thank you for taking the time to read this article.

If you have any recommendations about other packages, architectures, how to improve my code, English, or anything; please leave a comment or contact me through [Twitter](https://twitter.com/Carlos_marcv), or [LinkedIn](https://www.linkedin.com/in/carlos-marcano-a2135a134/).

The source code is [here](https://github.com/carlosm27/jwt_blacksheep_demo)

### References

- [Blacksheep's documentation](https://www.neoteroi.dev/blacksheep/authentication/#jwt-bearer)

- [GuardPost's Github Page](https://github.com/Neoteroi/GuardPost)

- [Build and Secure a FastAPI Server with Auth0](https://auth0.com/blog/build-and-secure-fastapi-server-with-auth0/)

- [Auth0's documentation](https://auth0.com/docs/articles)