quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.73k stars 2.67k forks source link

Keycloak Dev Services #30138

Closed iskhakovt closed 1 year ago

iskhakovt commented 1 year ago

Describe the bug

Keycloak Dev Services issuer doesn't match the expected configuration:

Caused by: org.jose4j.jwt.consumer.InvalidJwtException: JWT (claims-
{"exp":1672438567,"iat":1672437967,"jti":"f3694e7b-2d19-434c-8c26-273af214b030",
"iss":"http://localhost:45713/realms/quarkus","sub":"7da16905-87c9-436d-ba43-3bcb720914aa",
"typ":"Bearer","azp":"quarkus-app","session_state":"ef58267d-1c3f-4a4e-8966-fe720b427d95",
"scope":"microprofile-jwt","sid":"ef58267d-1c3f-4a4e-8966-fe720b427d95","upn":"alice","groups":["admin","user"]})
rejected due to invalid claims or other invalid content. Additional details: [[12] Issuer (iss) claim value
(http://localhost:45713/realms/quarkus) doesn't match expected value of http://keycloak-fardw:8080/realms/quarkus]

As far as I understand, in case of using a shared network we set the keycloak host to localhost while keycloak.url resolves into keycloak-[a-zA-Z0-9]5.

Expected behavior

KEYCLOAK_QUARKUS_HOSTNAME / KEYCLOAK_WILDFLY_FRONTEND_URL is set to the shared network hostname.

Actual behavior

KEYCLOAK_QUARKUS_HOSTNAME / KEYCLOAK_WILDFLY_FRONTEND_URL is hardcoded to localhost.

How to Reproduce?

I'm using this config mainly because I didn't manage to get OidcIdentityProvider to work with ServerInterceptor for grpc (due to the lack of RoutingContext):

mp.jwt.verify.publickey.location=${keycloak.url}/realms/quarkus/protocol/openid-connect/certs
mp.jwt.verify.issuer=${quarkus.oidc.auth-server-url}
smallrye.jwt.path.groups=realm_access/roles

Output of uname -a or ver

Linux ip-172-28-46-89 5.15.0-1021-aws #25~20.04.1-Ubuntu SMP Thu Sep 22 13:59:08 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk 17.0.5 2022-10-18

GraalVM version (if different from Java)

From quay.io/quarkus/ubi-quarkus-mandrel-builder-image:22.3-java17

Quarkus version or git rev

2.15.1.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 7.4

Additional information

No response

quarkus-bot[bot] commented 1 year ago

/cc @Karm(mandrel), @galderz(mandrel), @geoand(devservices), @pedroigor(keycloak), @sberyozkin(keycloak), @stuartwdouglas(devservices), @zakkak(mandrel)

sberyozkin commented 1 year ago

@iskhakovt

Can you please try mp.jwt.verify.issuer=${client.quarkus.oidc.auth-server-url} ?

iskhakovt commented 1 year ago

@sberyozkin that worked! Should it be updated in https://quarkus.io/guides/security-jwt#integration-testing-keycloak? ${keycloak.url} resolves into the wrong one.

sberyozkin commented 1 year ago

@iskhakovt Thanks,

Should it be updated in https://quarkus.io/guides/security-jwt#integration-testing-keycloak? ${keycloak.url} resolves into the wrong one.

Sure, with the shared network, client.quarkus.oidc.auth-server-url points to an address outside of the docker network (as explained by @geoand ), which is also why the frontend URL is set, in case of DevServices for KC to localhost.

Can you clarify please why it is a shared network setup in your case (to get a better doc message), In quarkus tests it happens if we have

<dependency>
           <groupId>io.quarkus</groupId>
            <artifactId>quarkus-container-image-jib</artifactId>
</dependency>

and <quarkus.container-image.build>true</quarkus.container-image.build> is set

iskhakovt commented 1 year ago

Not sure why that happens. :)

It doesn't happen on my local machine, but it does in CircleCI, using a machine executor (which should be just an aws node).

Run command:

./gradlew quarkusBuild quarkusIntTest \
  -Dquarkus.package.type=native \
  -Dquarkus.native.container-build=true -Dquarkus.container-image.build=true \
  -Dquarkus.docker.dockerfile-native-path=src/main/docker/Dockerfile.native-micro \
  -Dquarkus.native.builder-image=quay.io/quarkus/ubi-quarkus-mandrel-builder-image:22.3-java17 \
  -x check -x test

Dependencies:

dependencies {
  implementation enforcedPlatform("io.quarkus.platform:quarkus-bom:${quarkusVersion}")

  implementation 'io.quarkus:quarkus-arc'
  implementation 'io.quarkus:quarkus-core-deployment'
  implementation 'io.quarkus:quarkus-container-image-docker'
  implementation 'io.quarkus:quarkus-grpc'
  implementation 'io.quarkus:quarkus-kotlin'

  implementation 'io.quarkus:quarkus-hibernate-reactive-panache'
  runtimeOnly 'io.quarkus:quarkus-reactive-pg-client'

  implementation 'io.quarkus:quarkus-oidc'
  implementation 'io.quarkus:quarkus-smallrye-jwt'
  implementation 'io.quarkus:quarkus-smallrye-jwt-build'

  implementation 'org.jboss.slf4j:slf4j-jboss-logmanager'
  implementation 'org.jetbrains.kotlin:kotlin-reflect'
  implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'

  testImplementation 'io.quarkus:quarkus-junit5'
  testImplementation 'io.quarkus:quarkus-junit5-mockito'
  testImplementation 'io.quarkus:quarkus-test-security'
  testImplementation 'org.assertj:assertj-core:3.23.1'

  integrationTestImplementation 'io.quarkus:quarkus-junit5'
  integrationTestImplementation 'io.quarkus:quarkus-test-keycloak-server'

  if (project.osdetector.os == 'osx') {
    runtimeOnly "io.netty:netty-resolver-dns-native-macos:4.1.86.Final:osx-${project.osdetector.arch}"
  }
}

Host:

$ docker system info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Docker Buildx (Docker Inc., v0.9.1-docker)
  compose: Docker Compose (Docker Inc., v2.10.2)
  scan: Docker Scan (Docker Inc., v0.17.0)

Server:
 ...
 Server Version: 20.10.18
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  apparmor
  seccomp
   Profile: default
 Kernel Version: 5.15.0-1021-aws
 Operating System: Ubuntu 20.04.5 LTS
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 7.625GiB
 Name: ip-172-28-35-16
 ID: DDEY:ISRM:27AY:WCFS:CGZ6:2HVQ:OX2S:2QGV:UZVG:4GBH:GSOW:H5E4
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
sberyozkin commented 1 year ago

Thanks @iskhakovt.

Hey @geoand Can you please explain what is the general prerequisite for having a Quarkus application and a container like the one launched from DevServices for Keycloak have a shared docker network.

Is it Ok to say in the smallrye-jwt testing docs something simple like this:

If your Quarkus application is running in a docker container then it may share a network interface with the Keycloak docker container launched by DevServices for Keycloak.

In such cases, set 'mp.jwt.verify.issuer=${client.quarkus.oidc.auth-server-url}' instead of 'mp.jwt.verify.issuer=${quarkus.oidc.auth-server-url}'

?

geoand commented 1 year ago

@sberyozkin seems like already addressed it 😎