Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quarkus keycloak authorization usability improvements. #14851

Closed
pjgg opened this issue Feb 5, 2021 · 10 comments · Fixed by #39512
Closed

Quarkus keycloak authorization usability improvements. #14851

pjgg opened this issue Feb 5, 2021 · 10 comments · Fixed by #39512

Comments

@pjgg
Copy link
Contributor

pjgg commented Feb 5, 2021

Description

I would like to talk about how to quarkus-keycloak-authorization extension handler redirections and path exclusions because I think that could be improved from a usability point of view.

Scenario

So, let's imagine that we have a Rest application that is going to be deployed on openshift/k8s. Typically these applications use to have at least the following non-application endpoints:

  • /metrics
    • /metrics/vendor
    • /metrics/application
    • /metrics/base
  • /health
    • /health/live
    • /health/ready
    • /health/well
    • /health/group
  • /openapi
  • /swagger-ui

Most of them must be public or at least be accessible by the cluster (readiness/liveness probe), Prometheus... so, it seems reasonable to have the following configuration:

quarkus.http.root-path=/api

# authZ
quarkus.keycloak.policy-enforcer.enable=true

## Health
quarkus.keycloak.policy-enforcer.paths.health-redirection.path=/api/q/health
quarkus.keycloak.policy-enforcer.paths.health-redirection.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.health.path=/api/health/*
quarkus.keycloak.policy-enforcer.paths.health.enforcement-mode=DISABLED

## Metrics
quarkus.keycloak.policy-enforcer.paths.metrics-redirection.path=/api/q/metrics
quarkus.keycloak.policy-enforcer.paths.metrics-redirection.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.metrics.path=/api/metrics/*
quarkus.keycloak.policy-enforcer.paths.metrics.enforcement-mode=DISABLED

## OpenAPI
quarkus.keycloak.policy-enforcer.paths.openapi-redirection.path=/api/q/openapi
quarkus.keycloak.policy-enforcer.paths.openapi-redirection.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.openapi.path=/api/openapi/*
quarkus.keycloak.policy-enforcer.paths.openapi.enforcement-mode=DISABLED

## Swagger-ui
quarkus.keycloak.policy-enforcer.paths.swagger-ui-redirection.path=/api/q/swagger-ui
quarkus.keycloak.policy-enforcer.paths.swagger-ui-redirection.enforcement-mode=DISABLED
quarkus.keycloak.policy-enforcer.paths.swagger-ui.path=/api/swagger-ui/*
quarkus.keycloak.policy-enforcer.paths.swagger-ui.enforcement-mode=DISABLED

quarkus.oidc.auth-server-url=http://localhost:8180/auth/realms/test-realm
quarkus.oidc.client-id=test-application-client
quarkus.oidc.credentials.secret=test-application-client-secret
# tolerate 1 minute of clock skew between the Keycloak server and the application
quarkus.oidc.token.lifespan-grace=60

These configurations are not taking into account the application endpoint. This is just for platform endpoints. This config could be slightly improved if I group all redirections ( /q ), into one rule:

quarkus.http.root-path=/api

# authZ
quarkus.keycloak.policy-enforcer.enable=true
quarkus.keycloak.policy-enforcer.paths.health-redirection.path=/api/q/*
quarkus.keycloak.policy-enforcer.paths.health-redirection.enforcement-mode=DISABLED

quarkus.keycloak.policy-enforcer.paths.health.path=/api/health/*
quarkus.keycloak.policy-enforcer.paths.health.enforcement-mode=DISABLED
  

quarkus.keycloak.policy-enforcer.paths.metrics.path=/api/metrics/*
quarkus.keycloak.policy-enforcer.paths.metrics.enforcement-mode=DISABLED

quarkus.keycloak.policy-enforcer.paths.openapi.path=/api/openapi/*
quarkus.keycloak.policy-enforcer.paths.openapi.enforcement-mode=DISABLED

quarkus.keycloak.policy-enforcer.paths.swagger-ui.path=/api/swagger-ui/*
quarkus.keycloak.policy-enforcer.paths.swagger-ui.enforcement-mode=DISABLED

quarkus.oidc.auth-server-url=http://localhost:8180/auth/realms/test-realm
quarkus.oidc.client-id=test-application-client
quarkus.oidc.credentials.secret=test-application-client-secret
# tolerate 1 minute of clock skew between the Keycloak server and the application
quarkus.oidc.token.lifespan-grace=60

Note: this approach makes public all /api/q/* endpoints, so your business application can't have this path.

implementation ideas

As a developer I would like to group paths into one single rules:

Example:

quarkus.http.root-path=/api

# authZ
quarkus.keycloak.policy-enforcer.enable=true
quarkus.keycloak.policy-enforcer.paths.disabled.paths=/api/q/*, /api/health/*, /api/metrics/*, /api/openapi/*, /api/swagger-ui/*
quarkus.keycloak.policy-enforcer.paths.disabled.enforcement-mode=DISABLED

quarkus.oidc.auth-server-url=http://localhost:8180/auth/realms/test-realm
quarkus.oidc.client-id=test-application-client
quarkus.oidc.credentials.secret=test-application-client-secret
# tolerate 1 minute of clock skew between the Keycloak server and the application
quarkus.oidc.token.lifespan-grace=60

Also, I am not sure if Quarkus as a cloud-native framework that is, should handle by default all non-application redirections(and/or paths) and make them accessible from a Paas, as Openshift/k8s. I am not sure about that...

What do you think?

@pjgg pjgg added the kind/enhancement New feature or request label Feb 5, 2021
@ghost ghost added the area/kubernetes label Feb 5, 2021
@ghost
Copy link

ghost commented Feb 5, 2021

/cc @geoand

@geoand
Copy link
Contributor

geoand commented Feb 5, 2021

cc @sberyozkin

@sberyozkin
Copy link
Member

CC @pedroigor

@pedroigor
Copy link
Contributor

@pjgg It does make sense to define paths like that. It should be a trivial change. Do you have something implemented already? Otherwise, I'm going to work on it.

@pjgg
Copy link
Contributor Author

pjgg commented Feb 12, 2021

No, just the idea!. So, go for it!!!

@pjgg
Copy link
Contributor Author

pjgg commented Mar 16, 2021

There is a new Non-application endpoint implementation, where all non-application endpoint by default are under /q/, so these endpoints could be addressed by a config file like:

quarkus.keycloak.policy-enforcer.enable=true
quarkus.keycloak.policy-enforcer.paths.health-redirection.path=/q/*
quarkus.keycloak.policy-enforcer.paths.health-redirection.enforcement-mode=DISABLED

Support paths like:

quarkus.keycloak.policy-enforcer.enable=true
quarkus.keycloak.policy-enforcer.paths.disabled.paths=/api/q/*, /api/path_one/*, /api/path_two/*, /api/path_three/*
quarkus.keycloak.policy-enforcer.paths.disabled.enforcement-mode=DISABLED

Could be interesting from a usability point of view, but is not as critical.

@promosrene
Copy link

@pjgg Have you found a solution to your problem?

@pjgg
Copy link
Contributor Author

pjgg commented Nov 26, 2023

For the non-application endpoint sounds like the supported solution is this one:

quarkus.keycloak.policy-enforcer.enable=true
quarkus.keycloak.policy-enforcer.paths.health-redirection.path=/q/*
quarkus.keycloak.policy-enforcer.paths.health-redirection.enforcement-mode=DISABLED

If you want to skip another endpoints (business endpoint), I think that the only approach is to go one by one, or try to group this endpoint under a /public/* endpoint, and then follow the same strategy

quarkus.keycloak.policy-enforcer.enable=true
quarkus.keycloak.policy-enforcer.paths.public.path=/public/*
quarkus.keycloak.policy-enforcer.paths.public.enforcement-mode=DISABLED

@pedroigor WDYT ?

@promosrene
Copy link

This works for me too. But the actual behavior is a bit different from what the documentation says.

quarkus.keycloak.policy-enforcer.paths."paths".path mentions paths as:
"A URI relative to the context path of the application to be protected by the policy enforcer".
but in my tests it is not relative to quarkus.http.root-path.

Also, I understand from the documentation Using OpenID Connect (OIDC) and Keycloak to Centralize Authorization - Access to Public Resources that it's enough to define a quarkus.http.auth.permission.public.policy permission policy. But that did not work for me.

Maybe I made a mistake, but the different behavior of these two concepts in terms of relative versus absolute paths, as well as one versus multiple paths per policy, makes it difficult to get it to work.

@michalvavrik
Copy link
Member

quarkus.keycloak.policy-enforcer.paths."paths".path mentions paths as:
"A URI relative to the context path of the application to be protected by the policy enforcer".
but in my tests it is not relative to quarkus.http.root-path.

yep, let's fix that

Also, I understand from the documentation Using OpenID Connect (OIDC) and Keycloak to Centralize Authorization - Access to Public Resources that it's enough to define a quarkus.http.auth.permission.public.policy permission policy. But that did not work for me.

that's not enough information, please open new issue with a reproducer. what you describe is not related to this enhancement proposal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants