Recommended Approach for validation



  • Hi there,

    Been searching for a recommended approach to API security. We have to applications configured in Fusion Auth, we then use a gateway with JWT validation enabled that ensure the requestor has provided correct credentials (using JWKS). The call to the API is then passed on to the service behind the gateway. We have 2 services, one for each application.

    What is the recommended way in which to ensure the user making the call to the API is in fact allowed to access the API since the user will always pass the JWT validation, even if he did not register for the Application.



  • What is the recommended way in which to ensure the user making the call to the API is in fact allowed to access the API since the user will always pass the JWT validation, even if he did not register for the Application.

    The JWT will have different attributes if the user has registered for the application than if they haven't.

    For instance, the aud claim will be missing. You can (and should!) do validation beyond 'was this JWT signed correctly', such as checking the aud and iss claims. This article is worth a read.

    Here's a decoded JWT for a user who has logged in to a FusionAuth application which they are registered.

    {
      "aud": "bd535f7c-f184-44f5-9076-433fc3d716ca",
      "exp": 1592927915,
      "iat": 1592924315,
      "iss": "acme.com",
      "sub": "9df056ef-aca9-4cd6-9dc2-c7e5f1a7e44e",
      "authenticationType": "PASSWORD",
      "email": "forjwt@example.com",
      "email_verified": true,
      "roles": [],
      "applicationId": "bd535f7c-f184-44f5-9076-433fc3d716ca"
    }
    

    and here's a decoded JWT when they have logged in to a FusionAuth application to which they are not registered:

    {
      "exp": 1592928167,
      "iat": 1592924567,
      "iss": "acme.com",
      "sub": "9df056ef-aca9-4cd6-9dc2-c7e5f1a7e44e",
      "authenticationType": "PASSWORD",
      "email": "forjwt@example.com",
      "email_verified": true
    }
    

    One possible solution would be for the services to be configured with their corresponding FusionAuth application id and check the aud and applicationId claims. If they are missing or don't match the service's value, the JWT is not valid for the service.

    Hope this helps.



  • Since JWT claims are mentioned here I will join the question. From my experience, unregistered user's JWT claims differ based on authentication method. Ie. OAuth2 authentication flow will provide JWT featuring aud field, and JWTs generated via API authentication misses this field. I can't find any details on that in the docs, so my question is whether it works like this by design or is it an implementation detail? Right now, I'm relying on aud field presence in JWT provided by OAuth2 authentication flow and I'm curious whether I can believe that this behavior won't change in future releases.



  • @mgetka

    The JWT will never contain an aud claim if the user is not registered for that FusionAuth application. That is part of the design.



  • I've checked again and I cannot agree. For, an unregistered user, login API request of the following form

    {
        "loginId": "user",
        "password": "password123",
        "applicationId": "840ea92f-1eba-44bb-b168-75105f461c97"
    }
    

    creates JWT with following claims

    {
      "exp": 1593515224,
      "iat": 1593511624,
      "iss": "piedpiper.com",
      "sub": "43761079-cb20-4c0c-86e4-e3acfbefe6e2",
      "authenticationType": "PASSWORD",
      "preferred_username": "user"
    }
    

    But, authorization_code flow for the same application and user provides the token of the following form:

    {
      "aud": "840ea92f-1eba-44bb-b168-75105f461c97",
      "exp": 1593515655,
      "iat": 1593512055,
      "iss": "piedpiper.com",
      "sub": "43761079-cb20-4c0c-86e4-e3acfbefe6e2",
      "authenticationType": "PASSWORD",
      "preferred_username": "user"
    }
    

    So for OAuth2 there is no roles and applicationId, but aud is present. Anyway, I can see that I cannot rely on that 😁



  • Hmmm. That seems to be a bug, because the aud claim should be absent from the authorization code grant, since the user isn't registered for that application.

    I filed an issue: https://github.com/FusionAuth/fusionauth-issues/issues/713


Log in to reply