How to validate JWT token using identity server 4 in DRF?

Viewed 451

I have an idenityserver4, a front-end angular app, and a Django rest framework resource API. The Angular app is unaccessible if not logged, and redirect to the identityserver4. The user has to log in there and is redirected to the front-end. So far so good, the provider gives the front-end a JWT access token.

Then the frontend application asks for resources to the DRF API providing the JWT. That's where I'm stuck, all the tutorials I find on google explain how to create your own provider. But I just want to get the token, check with the identity server 4 that it's valid, authenticate the user, provide the resources

Any code snippet or library will be highly helpful.

Thanks.

1 Answers

I had a similar problem that I haven't fully solved, but maybe this can help you.

It is a permission class that only checks if a given jwt is properly encoded and signed using authlib, from there you can access the token internal information to do further validation.

permissions.py:

from authlib.jose import jwt
from rest_framework import permissions
from rest_framework.exceptions import APIException

class TokenNotValid(APIException):
    status_code = 403
    default_detail = "Invalid or absent JWT token field."

class NoAuthHeader(APIException):
    status_code = 403
    default_detail = "Absent 'Authorization' header."


class ValidJWTPermission(permissions.BasePermission):
    """
    Global permission check for JWT token.
    """

    def _get_pubkey(self):
        # You will probably need to change this to get the
        # public key from your identity server and not from a file.
        with open("../public.pem", "rb") as key_file:
            pubk = key_file.read()
        return pubk

    def has_permission(self, request, view):

        auth_header = request.META.get('HTTP_AUTHORIZATION')
        # print("Received header:")
        # print(auth_header)
        if auth_header is None:
            raise NoAuthHeader

        try:
            token = auth_header.split()[1]
            # print("Encoded Token:")
            # print(token)
            dec_token = jwt.decode(token,self._get_pubkey())
        except Exception:
            # Probably should add proper exception handling.
            raise TokenNotValid

        # print("Decoded token:")
        # print(dec_token)

        return True

views.py:

from .permissions import ValidJWTPermission

class HelloView(APIView):
    permission_classes = [ValidJWTPermission]

    def get(self, request):
        return HttpResponse("Hello, world. You're at the gerenciador index.")
Related