anarsultanov / keycloak-multi-tenancy

Keycloak extension for creating multi-tenant IAM for B2B SaaS applications.
Apache License 2.0
103 stars 11 forks source link

CORS issue when calling endpoints directly from my app #9

Closed geoffreyfourmis closed 6 months ago

geoffreyfourmis commented 7 months ago

Hello,

I have CORS issue when trying to call the APIs from my local frontend app image

image

while it is perfectly working with kcadm commands or directly with postman using the same user/brearer. I can't understand why it is not working directly inside my angular app (simple http get query with the bearer header)

I suspected something wrong with the "Web origins" config inside my client, because when I remove the host header in postman I got the same error image

I tried multiple value in the "Web origins" config without success.

I even tried with the realm "multi-tenant" json on the test resources but got the same error.

Sorry, I may have missed something but can't figure out why I can't reach your endpoints. Have you any idea ?

anarsultanov commented 7 months ago

Hello @geoffreyfourmis,

Are you experiencing the same issue when calling the default Keycloak REST API, or is it specific to extension endpoints?

If it's a general problem, you can try fixing it by adding your host to the "Web origins" in the Client configuration (or use "*" to allow all origins). In case the issue persists, refer to this resource for a detailed guide on debugging CORS issues.

I hope this helps! Let me know if you have any further questions.

github-actions[bot] commented 6 months ago

This issue is stale because it has been open for 30 days with no activity. If this issue still applies please comment otherwise it will be closed in 7 days.

github-actions[bot] commented 6 months ago

This issue was closed because it has been inactive for 7 days since being marked as stale.

geoffreyfourmis commented 5 months ago

Hi @anarsultanov, thanks for your anwser and sorry for the delay I had to work on something else.

I just did some other tests and I confirm that I have no issue calling the keycloak admin rest API

// working getting users from kc API
this.http.get(this.keycloak.getKeycloakInstance().authServerUrl + "/admin/realms/professionnels/users")
  .subscribe(users => {
    console.log(users);
  });

// not working getting tenants
this.http.get(this.keycloak.getKeycloakInstance().authServerUrl + "/realms/professionnels/tenants")
  .subscribe(tenants => {
    console.log(tenants);
  });

image

(but in postman both are working)

I will continue to investigate but if you have any idea it would be great

edit : it's not a localhost issue, I have the same behaviour deployed on a server

geoffreyfourmis commented 5 months ago

The problem seems to come from the preflight request wich produce an http 401.

Running this OPTIONS query :

curl "https://auth.mykcserver.fr/realms/myrealm/tenants" ^
  -X "OPTIONS" ^
  -H "Accept: */*" ^
  -H "Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7" ^
  -H "Access-Control-Request-Headers: authorization" ^
  -H "Access-Control-Request-Method: GET" ^
  -H "Cache-Control: no-cache" ^
  -H "Connection: keep-alive" ^
  -H "Origin: https://my-app-url.fr" ^
  -H "Pragma: no-cache" ^
  -H "Referer: https://my-app-url.fr/" ^
  -H "Sec-Fetch-Dest: empty" ^
  -H "Sec-Fetch-Mode: cors" ^
  -H "Sec-Fetch-Site: same-site" ^
  -H "User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36" ^
  --compressed

Produce this in keycloak log :

2024-01-19 13:31:10,299 DEBUG [org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext] (executor-thread-6) Restarting handler chain for exception exception: jakarta.ws.rs.NotAuthorizedException: HTTP 401 Unauthorized
        at dev.sultanov.keycloak.multitenancy.resource.AbstractAdminResource.setupAuth(AbstractAdminResource.java:56)
        at dev.sultanov.keycloak.multitenancy.resource.AbstractAdminResource.setup(AbstractAdminResource.java:47)
        at dev.sultanov.keycloak.multitenancy.resource.AbstractAdminResource.<init>(AbstractAdminResource.java:43)
        at dev.sultanov.keycloak.multitenancy.resource.TenantsResource.<init>(TenantsResource.java:32)
        at dev.sultanov.keycloak.multitenancy.resource.TenantsResourceProvider.getResource(TenantsResourceProvider.java:16)
        at org.keycloak.services.resources.RealmsResource.resolveRealmExtension(RealmsResource.java:265)
        at org.keycloak.services.resources.RealmsResource$quarkusrestinvoker$resolveRealmExtension_c7e400748748bf35309bc60d82a4789f2a0e2d02.invoke(Unknown Source)
        at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1623)

I'm not shure but looking quickly at the code I think we are trying to extract bearer from this query, but preflight query do not have bearer.