Firstly, most of the answers online suggest creating 2 separate
clients, one for the frontend (with public access) and one for the
backend (confidential client), but it doesn't seem to fit well because
Clients are applications and services that can request authentication
of a user, but the backend client isn't going to authenticate the
user. Only the frontend public client will do that and issue tokens.
So is it a good and recommended solution to do it like this?
As with most cases the answer is it depends. But let us break your statement bit by bit:
Firstly, most of the answers online suggest creating 2 separate
clients, one for the frontend (with public access) and one for the
backend (confidential client)
I can only speculate here, however, based on the links that you have provided in the comment section:
@dreamcrash Sure. I mostly relied on blog posts and StackOverflow
answers. To mention a few: medium.com/devops-dudes/… (Medium blog
post) stackoverflow.com/questions/65009654/…
stackoverflow.com/questions/72147402/…
If you read carefully the blog and the SO answers on those threads (first and second) they refer to the use of two clients, but those clients are public and bearer-only (not confidential).
(...) but it doesn't seem to fit well because Clients are applications and services that can request authentication of a user,
Not necessary; clients can also so be used solely for the purposes of authorization.
, but the backend client isn't going to authenticate the user.
Maybe not in your case, but a backend client can also be used for user authentication, depending on the use-case in question.
So is it a good and recommended solution to do it like this?
Depends
Typically, such tutorials (e.g., the blog that you referenced) are created to showcase the authentication and authorization capabilities of Keycloak.
The authentication part is showcased by the user authenticating via the browser (using the frontend client), whereas the authorization part is showcased by the application sending an access token to the Keycloak server where the claims on the access token (e.g., roles) can then be used to infer if the user has the permissions to perform the desire action (i.e., authorization).
Technically, even in those use-cases you are not force to use two clients. Alternatively to the approach that I have previously mentioned, one could have had a single client (i.e, the frontend client), and after the user has successfully authenticated, the application would pass the access token to the backend. The backend could then perform the authorization by directly checking, for instance, the roles in the access token, instead of relying on the Keycloak server to do so. There are pros and cons to both approaches.
A typical example where one could have two clients, a public and a confidential one, would be if the backend would be a separated micro-service that triggers some maintenance task for example. Assuming that task is not related at all to the user authentication process, it would make more sense to then have a separate client (in this case a confidential one) that would rely on the client credentials flow which is typically used for machine-to-machine use-cases.
As I have mentioned there are cases that you:
- only need a public client
- might need both public and a confidential client
- you just need a confidential client
For the last case, you can think about a server-side web application, in this case you can use either a public or a confidential client. Since, it is a server-side application (i.e., it can securely store a secret) then one should use a confidential client because (compared with the public client) it adds an extra layer of security (i.e., you also need to provide the client secret) to the authentication process.
Secondly, what is the need for 2 clients if the backend service can
verify authenticity of tokens via the token introspection API
endpoint?
I feel that this one was also answered. You do not really need to have two clients for this.
There is the the need for authorization. Permissions can only be
defined on confidential clients so you can't really do that in public
clients. Preferably resource permissions should be included in the
access token, but again you can't do that with a public client. If
there is a way to get permissions via Keycloak API, again it wouldn't
be the best solution because it would mean hitting the Keycloak API on
every request. Sure you can apply caching mechanisms, but it would
just add extra unnecessary overhead.
I feel that you might be mixing up concepts, namely public and confidential clients vs. frontend and backend. As I have mentioned, you can use public clients on the backend as well, albeit is sub-optimal. Regarding the permissions part, this again depends on the approach that you want to use to handle the authorization concerns, namely handling the authorization on the 1) Keycloak server or 2) in your backend. Have a look a this SO answer to better understand the trade-offs of one approach over the other.