Using Auth0 to authorize API requests from both our SPA and our other helper services

We have a single page application that calls our internal services (C # and Python) allowing these requests using the Auth0 SPA thread.

Our back-end services handle requests to each other as part of handling the request from the SPA user, so for the time being, we are just forwarding the authorization header from the SPA request, using it to authorize the operation for each service called.

Now I want to add processing work orders that will make requests between our services, making calls to existing endpoints. These requests will not have any existing auth header to forward, so they will need to be created.

Based on the Auth0 docs here and here , I believe that I should allow these requests using the Credentials Client grant, and I believe that our existing endpoints will therefore need to accept requests that are resolved in two different ways, from the SPA or from others services.

The problem is that JWTs from SPA are signed using one private key, and from services using corresponding secret keys. Is it correct that I need to configure my endpoints to accept JWTs generated using any of these secret keys?

So my main question is : Is this understanding correct, or should I do it in a completely different way?

More details:

There are two types of JWT authorization tokens that our endpoints need to handle:

1 Requests from our SPA containing:

sub: SPA-USER-ID
aud: SPA-CLIENT-ID

      

signed using HS256 (for historical reasons) using our secret SPA client.

2 Service requests containing:

sub: SERVICE-ID@clients
aud: API-ID
scope: ""

      

signed using HS256 (now for simplicity) using our customer service secret.

If one endpoint is going to decode and validate both requests, first, it fails because the "aud" values ​​are different. I believe that the "aud" value of our existing SPA calls is an error - it must be the identifier of the API receiving the request. Then the "aud" values ​​in both queries will be the same.

The next difference is that each is signed with a different private key - either the SPA or the calling service (and possibly with a different algorithm if I decide to make new service calls using RS256 as Auth0 recommends).

I can't seem to figure out the obvious ways of modifying early Python and C # starts to accept tokens encoded with different keys. I am thinking of coding it myself to manually try one and if it doesn't work try another. I'm sure I can do this for authorization on a Python endpoint that I wrote myself, based on Auth0 quickstart using PyJWT, but less familiar with our C # stuff, which is also based on Auth0 quickstart, but seems to use some built-in .NET JWT for middleware and I'm not at all sure if I can access its built-in functionality.

But if I'm doing it right then surely this is a general requirement?

Apologies if this question is poorly formed, I don't know anything about auth and read the Auth0 / Oath2 docs to figure it out as I go.

+3


source to share


1 answer


(Answering my question, third person)

Is this understanding correct, or should I do it in a completely different way?

The general flow shown in the question is correct. However, there is one widespread misunderstanding:

When services (or SPA) request new access tokens from Auth0 (or any issuer), the secret key they provide is usually not the one Auth0 uses to sign the returned token. Instead, the issuer uses the audience secret key (an API that will be called using this access token.)



The reason the OP got confused about this is because the code he inherited, as noted in the question, incorrectly passes the "audience" value of the SPA itself when requesting tokens. Therefore, the received tokens are signed using the SPA secrecy. Once this is fixed to use the API identifier as an "audience", then the tokens generated for the SPA, and those generated for the service-to-service calls, will be:

  • contain audience = API id and will therefore contain an equivalent payload in all respects except for "sub" (user id) and "scope" (not currently used).

  • must be signed with HS256 using the audience API-SECRET.

Therefore, the endpoint does not need to validate two different types of tokens encoded using two different secret keys. It can simply validate incoming requests using its own audience ID and its own private key, and this will successfully decode and validate requests from both the SPA and other services.

+2


source







All Articles