calling keycloak everytime from API server to fetch Authorization info

1.1k views Asked by At

I have Frontend application (spa) and this is calling rest api server.

As I need Authorization enabled, I have to create two client in Keycloak i.e. frontend(public) and backend(confidential).

I am passing an Access token fetched by frontend from Keycloak in Authorization header. Do REST api server need to call Keycloak every time to fetch Authorization info from provided access token. If yes, then it will increase the latency and what should be right approach then?

1

There are 1 answers

0
dreamcrash On

o REST api server need to call keycloak everytime to fetch Authorization info from provided access token. If yes, then it will increase the latency and what should be right approach then?

Yes, whenever one sends the access token to the Keycloak (KC) Server, one "pays" the corresponding performance penalty. That is a common problem when centralizing the authorization in a server. Fortunately, that problem can be solved in KC by configuring it to issue tokens with the user permissions already on it. Thus, the backend can locally inspect those tokens for the user permissions without having to perform additional calls to the KC server. You can read more about it in this link to the KC Authorization Server documentation. An example of such an token taken from that link:

{
  "authorization": {
      "permissions": [
        {
          "resource_set_id": "d2fe9843-6462-4bfc-baba-b5787bb6e0e7",
          "resource_set_name": "Hello World Resource"
        }
      ]
  },
  "jti": "d6109a09-78fd-4998-bf89-95730dfd0892-1464906679405",
  "exp": 1464906971,
  "nbf": 0,
  "iat": 1464906671,
  "sub": "f1888f4d-5172-4359-be0c-af338505d86c",
  "typ": "kc_ett",
  "azp": "hello-world-authz-service"
}

Do I need to invoke the server every time I want to introspect an RPT?

No. Just like a regular access token issued by a Keycloak server, RPTs also use the JSON web token (JWT) specification as the default format.

If you want to validate these tokens without a call to the remote introspection endpoint, you can decode the RPT and query for its validity locally. Once you decode the token, you can also use the permissions within the token to enforce authorization decisions.

Depending on your requirements, you can also try to reduce the number of calls to the KC server by caching the pair <user>/<resource to be accessed> along with the response if the user has or does not have permission to access it. In this manner, you do not need to constantly query the KC server on whether the user is allowed to access a given resource. The downside is that if the user access rights to that resource get updated (e.g., gains or loses a new role) the cache will contain outdated values. Therefore, you should invalidate your cache once in a while. This approach can potentially reduce the number of requests to the server but introduces more complexity on the client side and is more error-prone.

Another approach is for the KC client used for the frontend application to omit a token with all the information needed to allow your backend to determine whether the user has permission to access the resource. Hence, moving the Authorization responsibility from the KC server to your backend. IMO this one is the simplest and more performant solution. One of the downsides is that it tightly couples the authorization-related concerns with the domain concerns of the application. Consequently, changes to the authorization logic might result in changes to the code application.