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

Added CodeFlowAuthorizationTest #14173

Merged
merged 1 commit into from
Mar 14, 2021

Conversation

cemnura
Copy link
Contributor

@cemnura cemnura commented Jan 7, 2021

Fixes #10412

@cemnura cemnura changed the title Added CodeFlowAuthorizationTest [WIP] Added CodeFlowAuthorizationTest Jan 7, 2021
@cemnura
Copy link
Contributor Author

cemnura commented Jan 20, 2021

What did you mean by setting application-type=hybrid in all 3 application.properties because there is only one application.properties file in the IT test?

I converted the application-type to hybrid as you said for now.

Setting the application-type to hybrid fixed most of the previous BearerTokenAuthorizationTest test expect the following.

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running io.quarkus.it.keycloak.BearerTokenAuthorizationTest
2021-01-20 04:08:45,702 INFO  [org.ecl.jet.uti.log] (main) Logging initialized @5038ms to org.eclipse.jetty.util.log.Slf4jLog
2021-01-20 04:08:45,785 INFO  [org.ecl.jet.ser.Server] (main) jetty-9.4.30.v20200611; built: 2020-06-11T12:34:51.929Z; git: 271836e4c1f4612f12b7bb13ef5a92a927634b0d; jvm 11.0.9+11
2021-01-20 04:08:45,798 INFO  [org.ecl.jet.ser.han.ContextHandler] (main) Started o.e.j.s.ServletContextHandler@22e5ac71{/__admin,null,AVAILABLE}
2021-01-20 04:08:45,800 INFO  [org.ecl.jet.ser.han.ContextHandler] (main) Started o.e.j.s.ServletContextHandler@4ac58e7d{/,null,AVAILABLE}
2021-01-20 04:08:45,831 INFO  [org.ecl.jet.ser.AbstractConnector] (main) Started NetworkTrafficServerConnector@67bc78ec{HTTP/1.1, (http/1.1)}{0.0.0.0:64350}
2021-01-20 04:08:45,831 INFO  [org.ecl.jet.ser.Server] (main) Started @5167ms
2021-01-20 04:08:45,849 INFO  [io.qua.it.key.KeycloakTestResource] (main) Keycloak started in mock mode: http://localhost:64350
2021-01-20 04:08:46,613 INFO  [org.ecl.jet.ser.han.Con.ROOT] (qtp1892278266-80) RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.StubRequestHandler. Normalized mapped under returned 'null'
2021-01-20 04:08:46,761 INFO  [io.quarkus] (main) Quarkus 999-SNAPSHOT on JVM started in 2.752s. Listening on: http://localhost:8081
2021-01-20 04:08:46,762 INFO  [io.quarkus] (main) Profile test activated.
2021-01-20 04:08:46,762 INFO  [io.quarkus] (main) Installed features: [cdi, oidc, resteasy, resteasy-jackson, security]
[ERROR] WARNING: An illegal reflective access operation has occurred
[ERROR] WARNING: Illegal reflective access by org.codehaus.groovy.vmplugin.v9.Java9 (file:/Users/cemnura/.m2/repository/org/codehaus/groovy/groovy/3.0.7/groovy-3.0.7.jar) to constructor java.lang.AssertionError(java.lang.String)
[ERROR] WARNING: Please consider reporting this to the maintainers of org.codehaus.groovy.vmplugin.v9.Java9
[ERROR] WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
[ERROR] WARNING: All illegal access operations will be denied in a future release
2021-01-20 04:08:48,297 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-1) HTTP Request to /api/users/me failed, error id: c0a09626-bd02-4b5c-a81a-e9634796e3c6-1: java.lang.NullPointerException
        at io.vertx.ext.auth.oauth2.impl.flow.AuthCodeImpl.authorizeURL(AuthCodeImpl.java:64)
        at io.vertx.ext.auth.oauth2.impl.OAuth2AuthProviderImpl.authorizeURL(OAuth2AuthProviderImpl.java:326)
        at io.quarkus.oidc.runtime.CodeAuthenticationMechanism.getChallengeInternal(CodeAuthenticationMechanism.java:228)
        at io.quarkus.oidc.runtime.CodeAuthenticationMechanism$6.apply(CodeAuthenticationMechanism.java:189)
        at io.quarkus.oidc.runtime.CodeAuthenticationMechanism$6.apply(CodeAuthenticationMechanism.java:186)
        at io.smallrye.mutiny.operators.UniOnItemTransformToUni.invokeAndSubstitute(UniOnItemTransformToUni.java:31)
        at io.smallrye.mutiny.operators.UniOnItemTransformToUni$2.onItem(UniOnItemTransformToUni.java:74)
        at io.smallrye.mutiny.operators.UniSerializedSubscriber.onItem(UniSerializedSubscriber.java:86)
        at io.smallrye.mutiny.operators.uni.builders.KnownItemUni.subscribing(KnownItemUni.java:25)
        at io.smallrye.mutiny.operators.UniSerializedSubscriber.subscribe(UniSerializedSubscriber.java:54)
        at io.smallrye.mutiny.operators.UniSerializedSubscriber.subscribe(UniSerializedSubscriber.java:49)
        at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:30)
        at io.smallrye.mutiny.operators.UniOnItemTransformToUni.subscribing(UniOnItemTransformToUni.java:65)
        at io.smallrye.mutiny.operators.UniSerializedSubscriber.subscribe(UniSerializedSubscriber.java:54)
        at io.smallrye.mutiny.operators.UniSerializedSubscriber.subscribe(UniSerializedSubscriber.java:49)
        at io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:30)
        at io.smallrye.mutiny.operators.UniBlockingAwait.await(UniBlockingAwait.java:53)
        at io.smallrye.mutiny.groups.UniAwait.atMost(UniAwait.java:61)
        at io.smallrye.mutiny.groups.UniAwait.indefinitely(UniAwait.java:42)
        at io.quarkus.resteasy.runtime.UnauthorizedExceptionMapper.toResponse(UnauthorizedExceptionMapper.java:45)
        at io.quarkus.resteasy.runtime.UnauthorizedExceptionMapper.toResponse(UnauthorizedExceptionMapper.java:23)
        at org.jboss.resteasy.core.ExceptionHandler.executeExceptionMapper(ExceptionHandler.java:137)
        at org.jboss.resteasy.core.ExceptionHandler.unwrapException(ExceptionHandler.java:183)
        at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:104)
        at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:372)
        at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:218)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:519)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
        at org.jboss.resteasy.core.SynchronousDispatcher$$Lambda$732/000000000000000000.run(Unknown Source)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
        at org.jboss.resteasy.core.SynchronousDispatcher$$Lambda$734/000000000000000000.get(Unknown Source)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
        at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:138)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:41)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:93)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2415)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at java.base/java.lang.Thread.run(Thread.java:836)
        at org.jboss.threads.JBossThread.run(JBossThread.java:501)

[ERROR] Tests run: 5, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 7.225 s <<< FAILURE! - in io.quarkus.it.keycloak.BearerTokenAuthorizationTest
[ERROR] io.quarkus.it.keycloak.BearerTokenAuthorizationTest.testDeniedNoBearerToken  Time elapsed: 0.055 s  <<< FAILURE!
java.lang.AssertionError:
1 expectation failed.
Expected status code <401> but was <500>.

        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72)
        at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:59)
        at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:84)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:277)
        at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:493)
        at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure$validate$1.call(Unknown Source)
        at io.restassured.internal.ResponseSpecificationImpl.validateResponseIfRequired(ResponseSpecificationImpl.groovy:674)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoCachedMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:193)
        at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.callCurrent(PogoMetaMethodSite.java:61)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:185)
        at io.restassured.internal.ResponseSpecificationImpl.statusCode(ResponseSpecificationImpl.groovy:126)
        at io.restassured.specification.ResponseSpecification$statusCode$0.callCurrent(Unknown Source)
        at io.restassured.internal.ResponseSpecificationImpl.statusCode(ResponseSpecificationImpl.groovy:134)
        at io.restassured.internal.ValidatableResponseOptionsImpl.statusCode(ValidatableResponseOptionsImpl.java:89)
        at io.restassured.internal.ValidatableResponseImpl.super$2$statusCode(ValidatableResponseImpl.groovy)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1268)
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN(ScriptBytecodeAdapter.java:144)
        at io.restassured.internal.ValidatableResponseImpl.statusCode(ValidatableResponseImpl.groovy:142)
        at io.restassured.internal.ValidatableResponseImpl.statusCode(ValidatableResponseImpl.groovy)
        at io.quarkus.it.keycloak.BearerTokenAuthorizationTest.testDeniedNoBearerToken(BearerTokenAuthorizationTest.java:57)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:807)
        at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:714)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$167/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall$$Lambda$168/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$$Lambda$297/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
        at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
        at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$167/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall$$Lambda$168/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$$Lambda$297/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$321/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$247/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$246/000000000000000000.invoke(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$245/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$251/000000000000000000.accept(Unknown Source)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$247/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$246/000000000000000000.invoke(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$245/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$251/000000000000000000.accept(Unknown Source)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$247/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$246/000000000000000000.invoke(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$245/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator$$Lambda$209/000000000000000000.accept(Unknown Source)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:188)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:154)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:128)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
        at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
        at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)

2021-01-20 04:08:48,421 INFO  [io.quarkus] (main) Quarkus stopped in 0.015s
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR]   BearerTokenAuthorizationTest.testDeniedNoBearerToken:57 1 expectation failed.
Expected status code <401> but was <500>.

[INFO]
[ERROR] Tests run: 5, Failures: 1, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

The path variable in the following lines of vertx dependency is null

https://github.com/vert-x3/vertx-auth/blob/5c69d1bf7b948bb2ee2f9f2c9442062f7e881d90/vertx-auth-oauth2/src/main/java/io/vertx/ext/auth/oauth2/impl/flow/AuthCodeImpl.java#L63-L64

The same problems occures for BearerOpaqueTokenAuthorizationTest as well.

Could this be a missing configuration or mock again?

@sberyozkin
Copy link
Member

sberyozkin commented Jan 20, 2021

@cemnura oh, I'm sorry, for the moment I thought it was a quarkus unit test setup where per every test we'd have its own application properties.
OK, so for the bearer token tests (opaque and JWT tokens) we've been using a single properties file.

Now, if we want to test the code flow, then we can't replace the application type from service to web-app and expect it to work for the bearer token :-).
hybrid should generally help but now that I finally understand what the problem is, I'd suggest to avoid hybrid as it only works for simple hybrid cases where the code flow and bearer flows essentially have the same properties.
As such, we have 2 options:

  • multi-tenancy configuration - we'd separate the configuration
  • move the code flow tests into its own module

Would you like to try the multi-tenancy ?

Lets see how it goes, keep the original configuration intact, that would ensure both existing bearer token tests continue passing

Next update the new config like this:

quarkus.oidc.code-flow.auth-server-url=${keycloak.url}/realms/quarkus/
quarkus.oidc.code-flow.client-id=quarkus-web-app
quarkus.oidc.code-flow.credentials.secret=secret
quarkus.oidc.code-flow.application-type=web-app

note code-flow is a tenant id.
Next add a custom tenant config resolver, copy the one from

https://quarkus.io/guides/security-openid-connect-multitenancy#tenant-resolution-for-oidc-web-app-applications

but do not use a query check, use the path to check if it ends with the code-flow and if yes - return code-flow (this will pick up the correct configuration), otherwise return null.

And finally - update the test code and endpoint for the request URIs to end with /code-flow for your tenant resolver to find it

and that is it :-) Give it a try please

@cemnura
Copy link
Contributor Author

cemnura commented Jan 20, 2021

Tenant configuration sounds like a good idea that way we can separate the test.

I will try to configure the test with tenant before considering to making a separate module.

For the sake of not duplicating code 😄

@cemnura cemnura force-pushed the feature/oidc-wiremock-codeflow branch from 11db6c8 to 6d889b6 Compare January 20, 2021 23:17
@cemnura
Copy link
Contributor Author

cemnura commented Jan 20, 2021

I added the following configuration

quarkus.oidc.code-flow.auth-server-url=${keycloak.url}/realms/quarkus/
quarkus.oidc.code-flow.client-id=quarkus-web-app
quarkus.oidc.code-flow.credentials.secret=secret
quarkus.oidc.code-flow.application-type=web-app

Yet this lead to the following error.

It is as if the dynamic configuration that is loaded here by the KeycloakTestResource is not loaded because when I remove the tenant configuration the previous test run without a problem.

[ERROR] Tests run: 5, Failures: 0, Errors: 1, Skipped: 4, Time elapsed: 5.756 s <<< FAILURE! - in io.quarkus.it.keycloak.BearerOpaqueTokenAuthorizationTest
[ERROR] io.quarkus.it.keycloak.BearerOpaqueTokenAuthorizationTest.testSecureAccessSuccessPreferredUsername  Time elapsed: 0.013 s  <<< ERROR!
java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.test.junit.QuarkusTestExtension.throwBootFailureException(QuarkusTestExtension.java:564)
        at io.quarkus.test.junit.QuarkusTestExtension.interceptTestClassConstructor(QuarkusTestExtension.java:633)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        at org.junit.jupiter.api.extension.InvocationInterceptor.interceptTestClassConstructor(InvocationInterceptor.java:72)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:77)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestClassConstructor(ClassBasedTestDescriptor.java:342)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateTestClass(ClassBasedTestDescriptor.java:289)
        at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateTestClass(ClassTestDescriptor.java:79)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:267)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$2(ClassBasedTestDescriptor.java:259)
        at java.base/java.util.Optional.orElseGet(Optional.java:369)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$3(ClassBasedTestDescriptor.java:258)
        at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:101)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:100)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:65)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$1(NodeTestTask.java:111)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:111)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:79)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:188)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:154)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:128)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
        at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
        at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)
Caused by: java.lang.RuntimeException: Failed to start quarkus
        at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:653)
        at io.quarkus.runtime.Application.start(Application.java:90)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:567)
        at io.quarkus.runner.bootstrap.StartupActionImpl.run(StartupActionImpl.java:212)
        at io.quarkus.test.junit.QuarkusTestExtension.doJavaStart(QuarkusTestExtension.java:254)
        at io.quarkus.test.junit.QuarkusTestExtension.ensureStarted(QuarkusTestExtension.java:542)
        at io.quarkus.test.junit.QuarkusTestExtension.beforeAll(QuarkusTestExtension.java:577)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$8(ClassBasedTestDescriptor.java:368)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:368)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:192)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:136)
        ... 34 more
Caused by: io.quarkus.oidc.OIDCException: OIDC server is not available at the 'http://localhost:8180/auth/realms/quarkus' URL. Please make sure it is correct. Note it has to end with a realm value if you work with Keycloak, for example: 'https://localhost:8180/auth/realms/quarkus'
        at io.quarkus.oidc.runtime.OidcRecorder.toOidcException(OidcRecorder.java:307)
        at io.quarkus.oidc.runtime.OidcRecorder$2$1.handle(OidcRecorder.java:260)
        at io.quarkus.oidc.runtime.OidcRecorder$2$1.handle(OidcRecorder.java:256)
        at io.vertx.ext.auth.oauth2.providers.KeycloakAuth.lambda$discover$0(KeycloakAuth.java:125)
        at io.vertx.ext.auth.oauth2.providers.OpenIDConnectAuth.lambda$discover$2(OpenIDConnectAuth.java:104)
        at io.vertx.core.http.impl.HttpClientRequestBase.handleException(HttpClientRequestBase.java:133)
        at io.vertx.core.http.impl.HttpClientRequestImpl.handleException(HttpClientRequestImpl.java:370)
        at io.vertx.core.http.impl.HttpClientRequestImpl.lambda$null$6(HttpClientRequestImpl.java:472)
        at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:366)
        at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:43)
        at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:229)
        at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:221)
        at io.vertx.core.http.impl.HttpClientRequestImpl.lambda$connect$7(HttpClientRequestImpl.java:471)
        at io.vertx.core.http.impl.HttpClientImpl.lambda$getConnectionForRequest$4(HttpClientImpl.java:1048)
        at io.vertx.core.http.impl.ConnectionManager.lambda$getConnection$7(ConnectionManager.java:159)
        at io.vertx.core.http.impl.pool.Pool.connectFailed(Pool.java:397)
        at io.vertx.core.http.impl.pool.Pool.access$600(Pool.java:89)
        at io.vertx.core.http.impl.pool.Pool$Holder.lambda$connect$0(Pool.java:129)
        at io.vertx.core.impl.FutureImpl.tryFail(FutureImpl.java:195)
        at io.vertx.core.http.impl.HttpChannelConnector.connectFailed(HttpChannelConnector.java:255)
        at io.vertx.core.http.impl.HttpChannelConnector.lambda$doConnect$0(HttpChannelConnector.java:164)
        at io.vertx.core.net.impl.ChannelProvider.lambda$connect$1(ChannelProvider.java:78)
        at io.vertx.core.net.impl.ChannelProvider.lambda$handleConnect$2(ChannelProvider.java:145)
        at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:577)
        at io.netty.util.concurrent.DefaultPromise.notifyListeners0(DefaultPromise.java:570)
        at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:549)
        at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:490)
        at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:615)
        at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:608)
        at io.netty.util.concurrent.DefaultPromise.tryFailure(DefaultPromise.java:117)
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:321)
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:337)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:702)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:835)
Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:8180
Caused by: java.net.ConnectException: Connection refused
        at java.base/sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
        at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:779)
        at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:330)
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:334)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:702)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:835)

Copy link
Contributor Author

@cemnura cemnura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And finally - update the test code and endpoint for the request URIs to end with /code-flow for your tenant resolver to find it

I did not completely understand what to do here.

Should I add /code-flow to all endpoint? Such as admin and user?

Comment on lines 28 to 30
WebResponse webResponse = webClient
.loadWebResponse(new WebRequest(URI.create("http://localhost:8081/index.html").toURL()));
verifyLocationHeader(webClient, webResponse.getResponseHeaderValue("location"), null, "web-app", false);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also during the CodeFlowAuthorizationTest test the response header location value does return when accessing the static file at http://localhost:8081/index.html

Would you have any suggestions for how we could get the redirect value in the response header location?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cemnura Lets remove index.html resource and simply have a code flow endpoint with the path ending with /code-flow and use it here and it should be fine :-) (or you can also update the resolver to check if the path also ends with index.html)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will give it a shoot and get back to you. I think that the code-flow solution would be more logical 😄

@cemnura cemnura force-pushed the feature/oidc-wiremock-codeflow branch from ffc92c0 to ed9ec53 Compare January 20, 2021 23:53
@sberyozkin
Copy link
Member

Hi @cemnura re that connection error: Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:8180 - this is not a port created by Wiremock ?

@cemnura
Copy link
Contributor Author

cemnura commented Jan 21, 2021

Hi @cemnura re that connection error: Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: localhost/127.0.0.1:8180 - this is not a port created by Wiremock ?

Unfortunately no.

I thought that maybe the dynamic configuration of quarkus.oidc.auth-server-url is being somehow overrided by the tenant configuration.

So I changed the returned configuration here

to the following


        LOG.infof("Keycloak started in mock mode: %s", server.baseUrl());
        Map<String, String> conf = new HashMap<>();
        conf.put("quarkus.oidc.auth-server-url", server.baseUrl() + "/auth/realms/quarkus");
        conf.put("quarkus.oidc.code-flow.auth-server-url", server.baseUrl() + "/auth/realms/quarkus");

        return conf;

and this solved the problem. It is as if when the quarkus.oidc.auth-server-url is missing for the tenant the configuration is overrided to localhost/127.0.0.1:8180 which is probably read from the pom.xml

Would you consider this as a reasonable fix?

@sberyozkin
Copy link
Member

sberyozkin commented Jan 22, 2021

Hi @cemnura I'm not sure about it; looks like we are missing something here. What I don't understand is why it works when the default configuration is used - i.e - how does it pick up a correct Wiremock endpoint - while a few lines down the same property is initialized with the default value...
Oh, I see, so you have

return Collections.singletonMap("quarkus.oidc.auth-server-url", server.baseUrl() + "/auth/realms/quarkus");

should it be

return Collections.singletonMap("keycloak-url", server.baseUrl());

?
thanks

@cemnura
Copy link
Contributor Author

cemnura commented Jan 27, 2021

Hi @cemnura I'm not sure about it; looks like we are missing something here. What I don't understand is why it works when the default configuration is used - i.e - how does it pick up a correct Wiremock endpoint - while a few lines down the same property is initialized with the default value...
Oh, I see, so you have

return Collections.singletonMap("quarkus.oidc.auth-server-url", server.baseUrl() + "/auth/realms/quarkus");

should it be

return Collections.singletonMap("keycloak-url", server.baseUrl());

?
thanks

Hello @sberyozkin

I added the configuration check here to the properties that are dynamically with the test KeycloakTestResource and it enables previous test to work without a problem.

@cemnura
Copy link
Contributor Author

cemnura commented Jan 27, 2021

Now the only the codeflow test has to be complete. I will get back to you.

Thanks again for your help

@cemnura
Copy link
Contributor Author

cemnura commented Jan 27, 2021

@sberyozkin

I was able to get the CodeFlowAuthorizationTest to work now we only have to mock the login page?

2021-01-27 05:05:28,438 INFO  [org.ecl.jet.ser.han.Con.__admin] (qtp1019009267-33) RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.AdminRequestHandler. Normalized mapped under returned 'null'
2021-01-27 05:05:28,552 ERROR [WireMock] (qtp1019009267-33) 
                                               Request was not matched
                                               =======================

-----------------------------------------------------------------------------------------------------------------------
| Closest stub                                             | Request                                                  |
-----------------------------------------------------------------------------------------------------------------------
                                                           |
GET                                                        | GET
/auth/realms/quarkus/protocol/openid-connect/certs         | /auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%<<<<< URL does not match
                                                           | 3A8081%2Fcode-flow&state=f520ec4b-6509-47e7-a9ea-11dbda73
                                                           | a7a4&scope=openid&response_type=code&client_id=quarkus-we
                                                           | b-app
                                                           |
                                                           |
-----------------------------------------------------------------------------------------------------------------------

2021-01-27 05:05:28,561 INFO  [com.gar.htm.WebClient] (main) statusCode=[404] contentType=[text/plain]
2021-01-27 05:05:28,576 INFO  [com.gar.htm.WebClient] (main) 
                                               Request was not matched
                                               =======================

-----------------------------------------------------------------------------------------------------------------------
| Closest stub                                             | Request                                                  |
-----------------------------------------------------------------------------------------------------------------------
                                                           |
GET                                                        | GET
/auth/realms/quarkus/protocol/openid-connect/certs         | /auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%<<<<< URL does not match
                                                           | 3A8081%2Fcode-flow&state=f520ec4b-6509-47e7-a9ea-11dbda73
                                                           | a7a4&scope=openid&response_type=code&client_id=quarkus-we
                                                           | b-app
                                                           |
                                                           |
-----------------------------------------------------------------------------------------------------------------------



com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException: 404 Not Found for http://localhost:59882/auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=f520ec4b-6509-47e7-a9ea-11dbda73a7a4&scope=openid&response_type=code&client_id=quarkus-web-app

	at com.gargoylesoftware.htmlunit.WebClient.throwFailingHttpStatusCodeExceptionIfNecessary(WebClient.java:701)
	at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:461)
	at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:368)
	at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:520)
	at com.gargoylesoftware.htmlunit.WebClient.getPage(WebClient.java:501)
	at io.quarkus.it.keycloak.CodeFlowAuthorizationTest.testCodeFlow(CodeFlowAuthorizationTest.java:25)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:807)
	at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:714)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
	at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

@sberyozkin
Copy link
Member

@cemnura Hi, thanks, we are nearly there, please address a few minor cleanup comments; so the last difficult part is to emulate the challenge. I've commented about it in the issue, copying it here:

The authorization endpoint - this is where the main complexity will be.

When this endpoint is invoked (GET request) it needs to capture the state and redirect_uri query parameters and return the HTML form challenge with the fields as expected by the HtmlUnit test - more on it below - and this form should be able to **submit to another (non-discoverable) WireMock endpoint** - which would redirect back to Quarkus. This HTML form should likely be used to keep those state and redirect_uri values as the hidden form properties - or may be you can use the cookies to make it simpler.
Next, once HtmlUnit submits the form (username and password) - you'd redirect back to the value saved in redirect_uri but also add the saved state parameter as a query parameter and also add a code query parameter.

Next Vert.x would issue a code grant request (POST form) to the token endpoint - where that code and redirect_uri would be present - here you'd return the id token (JWT) - this token will be used to get the alice name, access token (JWT) and refresh token.

and
Note the name of the form fields (used by the HtmlUnitTest) - these are username and password

Does it help ?

Copy link
Contributor Author

@cemnura cemnura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cemnura Hi, thanks, we are nearly there, please address a few minor cleanup comments; so the last difficult part is to emulate the challenge. I've commented about it in the issue, copying it here:

The authorization endpoint - this is where the main complexity will be.

When this endpoint is invoked (GET request) it needs to capture the state and redirect_uri query parameters and return the HTML form challenge with the fields as expected by the HtmlUnit test - more on it below - and this form should be able to **submit to another (non-discoverable) WireMock endpoint** - which would redirect back to Quarkus. This HTML form should likely be used to keep those state and redirect_uri values as the hidden form properties - or may be you can use the cookies to make it simpler.
Next, once HtmlUnit submits the form (username and password) - you'd redirect back to the value saved in redirect_uri but also add the saved state parameter as a query parameter and also add a code query parameter.

Next Vert.x would issue a code grant request (POST form) to the token endpoint - where that code and redirect_uri would be present - here you'd return the id token (JWT) - this token will be used to get the alice name, access token (JWT) and refresh token.

and
Note the name of the form fields (used by the HtmlUnitTest) - these are username and password

Does it help ?

So we need to add a html response via WireMock when quarkus hits /auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%

If yes is there any example HTML?

And we will have to update the endpoint to mock the login request?

@cemnura
Copy link
Contributor Author

cemnura commented Feb 23, 2021

In all honesty I never been more happier to be able to login to an app 😄

@cemnura cemnura force-pushed the feature/oidc-wiremock-codeflow branch 2 times, most recently from c61c740 to af13405 Compare February 23, 2021 00:21
@cemnura
Copy link
Contributor Author

cemnura commented Feb 23, 2021

rebased 🎉

@cemnura cemnura changed the title [WIP] Added CodeFlowAuthorizationTest [Added CodeFlowAuthorizationTest Feb 23, 2021
@cemnura cemnura changed the title [Added CodeFlowAuthorizationTest Added CodeFlowAuthorizationTest Feb 23, 2021
@sberyozkin
Copy link
Member

@cemnura I think we will resolve the linked issue with this PR, I can then open a new issue to have this Witemock code re-usable... thanks

@cemnura
Copy link
Contributor Author

cemnura commented Feb 23, 2021

great to hear 🎉 I will re run the CI checks.

@cemnura cemnura force-pushed the feature/oidc-wiremock-codeflow branch 2 times, most recently from dfba954 to 76970f6 Compare February 23, 2021 22:18
@sberyozkin
Copy link
Member

Hey @cemnura Can you please check my 2 comments at https://github.com/quarkusio/quarkus/pull/14173/files#r580941716 ?

@cemnura
Copy link
Contributor Author

cemnura commented Feb 26, 2021

@sberyozkin

I added code, state and grant_type to the redirect URL for /login mock yet the application is still giving 401 Unauthorized.

Here is the URL request and response logs from wiremock.


2021-02-26 04:43:08.796 Request received:
127.0.0.1 - GET /login?username=alice&password=alice&state=49bc36d3-5cfa-4e33-87bd-6e5e0f698bc6&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow

Cookie: [q_auth_code-flow=49bc36d3-5cfa-4e33-87bd-6e5e0f698bc6]
Accept: [text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9]
Connection: [keep-alive]
User-Agent: [Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36]
Referer: [http://localhost:53966/auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=49bc36d3-5cfa-4e33-87bd-6e5e0f698bc6&scope=openid&response_type=code&client_id=quarkus-web-app]
Sec-Fetch-Site: [same-origin]
Sec-Fetch-Dest: [document]
Host: [localhost:53966]
Accept-Encoding: [gzip, deflate, br]
Sec-Fetch-Mode: [navigate]
Upgrade-Insecure-Requests: [1]
Sec-Fetch-User: [?1]
Accept-Language: [en-US]



Matched response definition:
{
  "status" : 302,
  "headers" : {
    "Location" : "http://localhost:8081/code-flow?code=fba12619-ca39-4b0a-9542-31764551cd04.07e08903-1263-4dd1-9fd1-4a59b0db5283.0ac5df91-e044-4051-bd03-106a3a5fb9cc&grant_type=authorization_code&state=49bc36d3-5cfa-4e33-87bd-6e5e0f698bc6"
  },
  "transformers" : [ "response-template" ]
}

Response:
HTTP/1.1 302
Location: [http://localhost:8081/code-flow?code=fba12619-ca39-4b0a-9542-31764551cd04.07e08903-1263-4dd1-9fd1-4a59b0db5283.0ac5df91-e044-4051-bd03-106a3a5fb9cc&grant_type=authorization_code&state=49bc36d3-5cfa-4e33-87bd-6e5e0f698bc6]
Matched-Stub-Id: [36e2387f-f166-4aa6-8e8a-00adc448a762]


[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 5.361 s <<< FAILURE! - in io.quarkus.it.keycloak.CodeFlowAuthorizationTest
[ERROR] io.quarkus.it.keycloak.CodeFlowAuthorizationTest.testCodeFlow  Time elapsed: 1.255 s  <<< ERROR!
com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException: 401 Unauthorized for http://localhost:8081/code-flow?code=fba12619-ca39-4b0a-9542-31764551cd04.07e08903-1263-4dd1-9fd1-4a59b0db5283.0ac5df91-e044-4051-bd03-106a3a5fb9cc&grant_type=authorization_code&state=49bc36d3-5cfa-4e33-87bd-6e5e0f698bc6

@sberyozkin
Copy link
Member

sberyozkin commented Feb 26, 2021

@cemnura authorization_code should not be added - instead you should add an extra stub for the token endpoint, expecting an authorization_grant request with the code and redirect_uri form parameters

@cemnura
Copy link
Contributor Author

cemnura commented Feb 27, 2021

@sberyozkin I added a stub for /token. The application is not getting redirected to the /token URL.

How should redirect the application to the '/token' URL after clicking the Login button.

Currently the login button action is to make a request to /login.

Thanks for your patience and help 😄

@sberyozkin
Copy link
Member

Hi @cemnura sure, after Wiremock returns the redirect request to the HtmlUnit browser, it follows it to Quarkus - this is where it will send a direct authorization_code token grant request to the token endpoint - perhaps you can enable the TRACE logging for CodeAuthenticationFlow ? (see how to enable it in integration-tests/oidc-code-flow) or even debug
thanks

@sberyozkin
Copy link
Member

@cemnura
Copy link
Contributor Author

cemnura commented Mar 7, 2021

Hello @sberyozkin

I managed to correctly redirect with state and code and got the app to make a request to the token endpoint (Added token_endpoint to .well-known/openid-configuration).

Yet the login page is reappearing Even though the token is being introspected.

Shouldn't the quarkus app be responding at this point?

Logs after loign button pressed.

2021-03-07 03:02:10.147 Request received:
127.0.0.1 - GET /login?username=alice&password=alice&state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow

Cookie: [q_auth_code-flow=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e]
Accept: [text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9]
Connection: [keep-alive]
User-Agent: [Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36]
Referer: [http://localhost:62695/auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&scope=openid&response_type=code&client_id=quarkus-web-app]
Sec-Fetch-Site: [same-origin]
Sec-Fetch-Dest: [document]
Host: [localhost:62695]
Accept-Encoding: [gzip, deflate, br]
Sec-Fetch-Mode: [navigate]
Upgrade-Insecure-Requests: [1]
Sec-Fetch-User: [?1]
Accept-Language: [en-US]



Matched response definition:
{
  "status" : 302,
  "headers" : {
    "Location" : "http://localhost:8081/code-flow?state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&code=58af24f2-9093-4674-a431-4a9d66be719c.50437113-cd78-48a2-838e-b936fe458c5d.0ac5df91-e044-4051-bd03-106a3a5fb9cc"
  },
  "transformers" : [ "response-template" ]
}

Response:
HTTP/1.1 302
Location: [http://localhost:8081/code-flow?state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&code=58af24f2-9093-4674-a431-4a9d66be719c.50437113-cd78-48a2-838e-b936fe458c5d.0ac5df91-e044-4051-bd03-106a3a5fb9cc]
Matched-Stub-Id: [b60ef195-01e1-4d90-aa5f-aa6b312caeb3]


2021-03-07 03:02:10,152 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (vert.x-eventloop-thread-1) Token request redirect_uri parameter: http://localhost:8081/code-flow
2021-03-07 03:02:10.157 Request received:
127.0.0.1 - POST /auth/realms/quarkus/token

Authorization: [Basic cXVhcmt1cy13ZWItYXBwOnNlY3JldA==]
Accept: [application/json,application/x-www-form-urlencoded;q=0.9]
Host: [localhost:62695]
Content-Length: [200]
Content-Type: [application/x-www-form-urlencoded]
code=58af24f2-9093-4674-a431-4a9d66be719c.50437113-cd78-48a2-838e-b936fe458c5d.0ac5df91-e044-4051-bd03-106a3a5fb9cc&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&grant_type=authorization_code


Matched response definition:
{
  "status" : 200,
  "body" : "{\n  \"access_token\": \"fba12619-ca39-4b0a-9542-31764551cd04\",\n  \"refresh_token\": \"07e08903-1263-4dd1-9fd1-4a59b0db5283\",\n  \"id_token\": \"alice\",\n  \"token_type\": \"Bearer\"\n}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

Response:
HTTP/1.1 200
Content-Type: [application/json]
Matched-Stub-Id: [cfb5551d-d9a6-4d70-b79e-cbe48cdcb34b]


2021-03-07 03:02:10.180 Request received:
127.0.0.1 - POST /auth/realms/quarkus/protocol/openid-connect/token/introspect

Authorization: [Basic cXVhcmt1cy13ZWItYXBwOnNlY3JldA==]
Accept: [application/json,application/x-www-form-urlencoded;q=0.9]
Host: [localhost:62695]
Content-Length: [40]
Content-Type: [application/x-www-form-urlencoded]
token=alice&token_type_hint=access_token


Matched response definition:
{
  "status" : 200,
  "body" : "{\"active\":true,\"scope\":\"user\",\"username\":\"alice\",\"iat\":1,\"exp\":999999999999,\"expires_in\":999999999999,\"client_id\":\"quarkus-web-app\"}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

Response:
HTTP/1.1 200
Content-Type: [application/json]
Matched-Stub-Id: [0566271e-2046-4cd6-b090-b6bc1612e935]


2021-03-07 03:02:10,186 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (vert.x-eventloop-thread-1) Authentication request redirect_uri parameter: http://localhost:8081/code-flow
2021-03-07 03:02:10,186 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (vert.x-eventloop-thread-1) q_auth_code-flow cookie 'max-age' parameter is set to 1800
2021-03-07 03:02:10.192 Request received:
127.0.0.1 - GET /auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=f9d1bcfc-d335-4b3b-bcee-a98978a3acdd&scope=openid&response_type=code&client_id=quarkus-web-app

Cookie: [q_auth_code-flow=f9d1bcfc-d335-4b3b-bcee-a98978a3acdd|/code-flow?state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&code=58af24f2-9093-4674-a431-4a9d66be719c.50437113-cd78-48a2-838e-b936fe458c5d.0ac5df91-e044-4051-bd03-106a3a5fb9cc]
Accept: [text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9]
Connection: [keep-alive]
User-Agent: [Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36]
Referer: [http://localhost:62695/auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&scope=openid&response_type=code&client_id=quarkus-web-app]
Sec-Fetch-Site: [same-origin]
Sec-Fetch-Dest: [document]
Host: [localhost:62695]
Accept-Encoding: [gzip, deflate, br]
Sec-Fetch-Mode: [navigate]
Upgrade-Insecure-Requests: [1]
Sec-Fetch-User: [?1]
Accept-Language: [en-US]



Matched response definition:
{
  "status" : 200,
  "body" : "<html>\n<body>\n <form action=\"/login\" name=\"form\">\n  <input type=\"text\" id=\"username\" name=\"username\"/>\n  <input type=\"password\" id=\"password\" name=\"password\"/>\n  <input type=\"hidden\" id=\"state\" name=\"state\" value=\"f9d1bcfc-d335-4b3b-bcee-a98978a3acdd\"/>\n  <input type=\"hidden\" id=\"redirect_uri\" name=\"redirect_uri\" value=\"http://localhost:8081/code-flow\"/>\n  <input type=\"submit\" id=\"login\" value=\"login\"/>\n</form>\n</body>\n</html> ",
  "headers" : {
    "Content-Type" : "text/html"
  },
  "transformers" : [ "response-template" ]
}

Response:
HTTP/1.1 200
Content-Type: [text/html]
Matched-Stub-Id: [1c30ecb8-e3f1-4c0f-8f08-e01f936f8e53]

@cemnura
Copy link
Contributor Author

cemnura commented Mar 10, 2021

Full logs

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running io.quarkus.it.keycloak.CodeFlowAuthorizationTest
2021-03-07 03:02:04.826 Verbose logging enabled
2021-03-07 03:02:05,296 INFO  [org.ecl.jet.uti.log] (main) Logging initialized @7025ms to org.eclipse.jetty.util.log.Slf4jLog
2021-03-07 03:02:05,459 INFO  [org.ecl.jet.ser.Server] (main) jetty-9.4.30.v20200611; built: 2020-06-11T12:34:51.929Z; git: 271836e4c1f4612f12b7bb13ef5a92a927634b0d; jvm 11.0.9+11
2021-03-07 03:02:05,491 INFO  [org.ecl.jet.ser.han.ContextHandler] (main) Started o.e.j.s.ServletContextHandler@2aa749d4{/__admin,null,AVAILABLE}
2021-03-07 03:02:05,494 INFO  [org.ecl.jet.ser.han.ContextHandler] (main) Started o.e.j.s.ServletContextHandler@27e8fb9e{/,null,AVAILABLE}
2021-03-07 03:02:05,548 INFO  [org.ecl.jet.ser.AbstractConnector] (main) Started NetworkTrafficServerConnector@ad6dc6bf{HTTP/1.1, (http/1.1)}{0.0.0.0:62695}
2021-03-07 03:02:05,548 INFO  [org.ecl.jet.ser.Server] (main) Started @7277ms
2021-03-07 03:02:05,568 INFO  [io.qua.it.key.KeycloakTestResource] (main) Keycloak started in mock mode: http://localhost:62695
2021-03-07 03:02:07,423 INFO  [org.ecl.jet.ser.han.Con.ROOT] (qtp791147356-79) RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.StubRequestHandler. Normalized mapped under returned 'null'
2021-03-07 03:02:07.487 Request received:
127.0.0.1 - GET /auth/realms/quarkus/.well-known/openid-configuration

Accept: [application/json]
Host: [localhost:62695]



Matched response definition:
{
  "status" : 200,
  "body" : "{\n    \"jwks_uri\": \"http://localhost:62695/auth/realms/quarkus/protocol/openid-connect/certs\",\n    \"token_introspection_endpoint\": \"http://localhost:62695/auth/realms/quarkus/protocol/openid-connect/token/introspect\",\n    \"authorization_endpoint\": \"http://localhost:62695/auth/realms/quarkus\",    \"token_endpoint\": \"http://localhost:62695/auth/realms/quarkus/token\"}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

Response:
HTTP/1.1 200
Content-Type: [application/json]
Matched-Stub-Id: [acf392f8-b206-4763-a868-0a6e150ea9b2]


2021-03-07 03:02:07.531 Request received:
127.0.0.1 - GET /auth/realms/quarkus/protocol/openid-connect/certs

Accept: [application/json, application/jwk-set+json]
Host: [localhost:62695]



Matched response definition:
{
  "status" : 200,
  "body" : "{\n  \"keys\" : [\n    {\n      \"kid\": \"1\",\n      \"kty\":\"RSA\",\n      \"n\":\"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ\",\n      \"e\":\"AQAB\"\n    }\n  ]\n}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

Response:
HTTP/1.1 200
Content-Type: [application/json]
Matched-Stub-Id: [a87c9ebb-c54e-499c-90a6-a05cfe33f4ab]


2021-03-07 03:02:07.542 Request received:
127.0.0.1 - GET /auth/realms/quarkus/.well-known/openid-configuration

Accept: [application/json]
Host: [localhost:62695]



Matched response definition:
{
  "status" : 200,
  "body" : "{\n    \"jwks_uri\": \"http://localhost:62695/auth/realms/quarkus/protocol/openid-connect/certs\",\n    \"token_introspection_endpoint\": \"http://localhost:62695/auth/realms/quarkus/protocol/openid-connect/token/introspect\",\n    \"authorization_endpoint\": \"http://localhost:62695/auth/realms/quarkus\",    \"token_endpoint\": \"http://localhost:62695/auth/realms/quarkus/token\"}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

Response:
HTTP/1.1 200
Content-Type: [application/json]
Matched-Stub-Id: [acf392f8-b206-4763-a868-0a6e150ea9b2]


2021-03-07 03:02:07.547 Request received:
127.0.0.1 - GET /auth/realms/quarkus/protocol/openid-connect/certs

Accept: [application/json, application/jwk-set+json]
Host: [localhost:62695]



Matched response definition:
{
  "status" : 200,
  "body" : "{\n  \"keys\" : [\n    {\n      \"kid\": \"1\",\n      \"kty\":\"RSA\",\n      \"n\":\"iJw33l1eVAsGoRlSyo-FCimeOc-AaZbzQ2iESA3Nkuo3TFb1zIkmt0kzlnWVGt48dkaIl13Vdefh9hqw_r9yNF8xZqX1fp0PnCWc5M_TX_ht5fm9y0TpbiVmsjeRMWZn4jr3DsFouxQ9aBXUJiu26V0vd2vrECeeAreFT4mtoHY13D2WVeJvboc5mEJcp50JNhxRCJ5UkY8jR_wfUk2Tzz4-fAj5xQaBccXnqJMu_1C6MjoCEiB7G1d13bVPReIeAGRKVJIF6ogoCN8JbrOhc_48lT4uyjbgnd24beatuKWodmWYhactFobRGYo5551cgMe8BoxpVQ4to30cGA0qjQ\",\n      \"e\":\"AQAB\"\n    }\n  ]\n}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

Response:
HTTP/1.1 200
Content-Type: [application/json]
Matched-Stub-Id: [a87c9ebb-c54e-499c-90a6-a05cfe33f4ab]


2021-03-07 03:02:08,490 INFO  [io.quarkus] (main) Quarkus 999-SNAPSHOT on JVM started in 5.996s. Listening on: http://localhost:8081
2021-03-07 03:02:08,491 INFO  [io.quarkus] (main) Profile test activated. 
2021-03-07 03:02:08,491 INFO  [io.quarkus] (main) Installed features: [cdi, oidc, resteasy, resteasy-jackson, security]
2021-03-07 03:02:09,870 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (executor-thread-1) Authentication request redirect_uri parameter: http://localhost:8081/code-flow
2021-03-07 03:02:09,871 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (executor-thread-1) q_auth_code-flow cookie 'max-age' parameter is set to 1800
2021-03-07 03:02:09.970 Request received:
127.0.0.1 - GET /auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&scope=openid&response_type=code&client_id=quarkus-web-app

Cookie: [q_auth_code-flow=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e]
Accept: [text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9]
Upgrade-Insecure-Requests: [1]
Connection: [keep-alive]
User-Agent: [Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36]
Sec-Fetch-Site: [same-origin]
Sec-Fetch-Dest: [document]
Host: [localhost:62695]
Sec-Fetch-User: [?1]
Accept-Encoding: [gzip, deflate, br]
Accept-Language: [en-US]
Sec-Fetch-Mode: [navigate]



Matched response definition:
{
  "status" : 200,
  "body" : "<html>\n<body>\n <form action=\"/login\" name=\"form\">\n  <input type=\"text\" id=\"username\" name=\"username\"/>\n  <input type=\"password\" id=\"password\" name=\"password\"/>\n  <input type=\"hidden\" id=\"state\" name=\"state\" value=\"08f5b4fe-c092-491b-9a45-bfc39e6b1e5e\"/>\n  <input type=\"hidden\" id=\"redirect_uri\" name=\"redirect_uri\" value=\"http://localhost:8081/code-flow\"/>\n  <input type=\"submit\" id=\"login\" value=\"login\"/>\n</form>\n</body>\n</html> ",
  "headers" : {
    "Content-Type" : "text/html"
  },
  "transformers" : [ "response-template" ]
}

Response:
HTTP/1.1 200
Content-Type: [text/html]
Matched-Stub-Id: [1c30ecb8-e3f1-4c0f-8f08-e01f936f8e53]


2021-03-07 03:02:10.147 Request received:
127.0.0.1 - GET /login?username=alice&password=alice&state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow

Cookie: [q_auth_code-flow=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e]
Accept: [text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9]
Connection: [keep-alive]
User-Agent: [Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36]
Referer: [http://localhost:62695/auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&scope=openid&response_type=code&client_id=quarkus-web-app]
Sec-Fetch-Site: [same-origin]
Sec-Fetch-Dest: [document]
Host: [localhost:62695]
Accept-Encoding: [gzip, deflate, br]
Sec-Fetch-Mode: [navigate]
Upgrade-Insecure-Requests: [1]
Sec-Fetch-User: [?1]
Accept-Language: [en-US]



Matched response definition:
{
  "status" : 302,
  "headers" : {
    "Location" : "http://localhost:8081/code-flow?state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&code=58af24f2-9093-4674-a431-4a9d66be719c.50437113-cd78-48a2-838e-b936fe458c5d.0ac5df91-e044-4051-bd03-106a3a5fb9cc"
  },
  "transformers" : [ "response-template" ]
}

Response:
HTTP/1.1 302
Location: [http://localhost:8081/code-flow?state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&code=58af24f2-9093-4674-a431-4a9d66be719c.50437113-cd78-48a2-838e-b936fe458c5d.0ac5df91-e044-4051-bd03-106a3a5fb9cc]
Matched-Stub-Id: [b60ef195-01e1-4d90-aa5f-aa6b312caeb3]


2021-03-07 03:02:10,152 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (vert.x-eventloop-thread-1) Token request redirect_uri parameter: http://localhost:8081/code-flow
2021-03-07 03:02:10.157 Request received:
127.0.0.1 - POST /auth/realms/quarkus/token

Authorization: [Basic cXVhcmt1cy13ZWItYXBwOnNlY3JldA==]
Accept: [application/json,application/x-www-form-urlencoded;q=0.9]
Host: [localhost:62695]
Content-Length: [200]
Content-Type: [application/x-www-form-urlencoded]
code=58af24f2-9093-4674-a431-4a9d66be719c.50437113-cd78-48a2-838e-b936fe458c5d.0ac5df91-e044-4051-bd03-106a3a5fb9cc&redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&grant_type=authorization_code


Matched response definition:
{
  "status" : 200,
  "body" : "{\n  \"access_token\": \"fba12619-ca39-4b0a-9542-31764551cd04\",\n  \"refresh_token\": \"07e08903-1263-4dd1-9fd1-4a59b0db5283\",\n  \"id_token\": \"alice\",\n  \"token_type\": \"Bearer\"\n}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

Response:
HTTP/1.1 200
Content-Type: [application/json]
Matched-Stub-Id: [cfb5551d-d9a6-4d70-b79e-cbe48cdcb34b]


2021-03-07 03:02:10.180 Request received:
127.0.0.1 - POST /auth/realms/quarkus/protocol/openid-connect/token/introspect

Authorization: [Basic cXVhcmt1cy13ZWItYXBwOnNlY3JldA==]
Accept: [application/json,application/x-www-form-urlencoded;q=0.9]
Host: [localhost:62695]
Content-Length: [40]
Content-Type: [application/x-www-form-urlencoded]
token=alice&token_type_hint=access_token


Matched response definition:
{
  "status" : 200,
  "body" : "{\"active\":true,\"scope\":\"user\",\"username\":\"alice\",\"iat\":1,\"exp\":999999999999,\"expires_in\":999999999999,\"client_id\":\"quarkus-web-app\"}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

Response:
HTTP/1.1 200
Content-Type: [application/json]
Matched-Stub-Id: [0566271e-2046-4cd6-b090-b6bc1612e935]


2021-03-07 03:02:10,186 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (vert.x-eventloop-thread-1) Authentication request redirect_uri parameter: http://localhost:8081/code-flow
2021-03-07 03:02:10,186 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (vert.x-eventloop-thread-1) q_auth_code-flow cookie 'max-age' parameter is set to 1800
2021-03-07 03:02:10.192 Request received:
127.0.0.1 - GET /auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=f9d1bcfc-d335-4b3b-bcee-a98978a3acdd&scope=openid&response_type=code&client_id=quarkus-web-app

Cookie: [q_auth_code-flow=f9d1bcfc-d335-4b3b-bcee-a98978a3acdd|/code-flow?state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&code=58af24f2-9093-4674-a431-4a9d66be719c.50437113-cd78-48a2-838e-b936fe458c5d.0ac5df91-e044-4051-bd03-106a3a5fb9cc]
Accept: [text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9]
Connection: [keep-alive]
User-Agent: [Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36]
Referer: [http://localhost:62695/auth/realms/quarkus?redirect_uri=http%3A%2F%2Flocalhost%3A8081%2Fcode-flow&state=08f5b4fe-c092-491b-9a45-bfc39e6b1e5e&scope=openid&response_type=code&client_id=quarkus-web-app]
Sec-Fetch-Site: [same-origin]
Sec-Fetch-Dest: [document]
Host: [localhost:62695]
Accept-Encoding: [gzip, deflate, br]
Sec-Fetch-Mode: [navigate]
Upgrade-Insecure-Requests: [1]
Sec-Fetch-User: [?1]
Accept-Language: [en-US]



Matched response definition:
{
  "status" : 200,
  "body" : "<html>\n<body>\n <form action=\"/login\" name=\"form\">\n  <input type=\"text\" id=\"username\" name=\"username\"/>\n  <input type=\"password\" id=\"password\" name=\"password\"/>\n  <input type=\"hidden\" id=\"state\" name=\"state\" value=\"f9d1bcfc-d335-4b3b-bcee-a98978a3acdd\"/>\n  <input type=\"hidden\" id=\"redirect_uri\" name=\"redirect_uri\" value=\"http://localhost:8081/code-flow\"/>\n  <input type=\"submit\" id=\"login\" value=\"login\"/>\n</form>\n</body>\n</html> ",
  "headers" : {
    "Content-Type" : "text/html"
  },
  "transformers" : [ "response-template" ]
}

Response:
HTTP/1.1 200
Content-Type: [text/html]
Matched-Stub-Id: [1c30ecb8-e3f1-4c0f-8f08-e01f936f8e53]


[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 11.392 s <<< FAILURE! - in io.quarkus.it.keycloak.CodeFlowAuthorizationTest
[ERROR] io.quarkus.it.keycloak.CodeFlowAuthorizationTest.testCodeFlow  Time elapsed: 1.734 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <Welcome to Test App> but was: <>
        at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
        at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
        at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
        at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
        at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1124)
        at io.quarkus.it.keycloak.CodeFlowAuthorizationTest.testCodeFlow(CodeFlowAuthorizationTest.java:35)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at io.quarkus.test.junit.QuarkusTestExtension.runExtensionMethod(QuarkusTestExtension.java:807)
        at io.quarkus.test.junit.QuarkusTestExtension.interceptTestMethod(QuarkusTestExtension.java:714)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$172/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall$$Lambda$173/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$$Lambda$857/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
        at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
        at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$172/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall$$Lambda$173/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$$Lambda$857/000000000000000000.apply(Unknown Source)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$927/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$253/000000000000000000.invoke(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$252/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$258/000000000000000000.accept(Unknown Source)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$253/000000000000000000.invoke(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$252/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$258/000000000000000000.accept(Unknown Source)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$254/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$253/000000000000000000.invoke(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$252/000000000000000000.execute(Unknown Source)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator$$Lambda$216/000000000000000000.accept(Unknown Source)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.execute(JUnitPlatformProvider.java:188)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:154)
        at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:128)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
        at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
        at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)

2021-03-07 03:02:10,291 INFO  [io.quarkus] (main) Quarkus stopped in 0.022s
[INFO] 
[INFO] Results:
[INFO] 
[ERROR] Failures: 
[ERROR]   CodeFlowAuthorizationTest.testCodeFlow:35 expected: <Welcome to Test App> but was: <>
[INFO] 
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  23.448 s
[INFO] Finished at: 2021-03-07T03:02:10+03:00
[INFO] ------------------------------------------------------------------------

@sberyozkin
Copy link
Member

@cemnura I'm not sure 100% but it looks like the problem is that you are returning the wrong token values:

{
  "status" : 200,
  "body" : "{\n  \"access_token\": \"fba12619-ca39-4b0a-9542-31764551cd04\",\n  \"refresh_token\": \"07e08903-1263-4dd1-9fd1-4a59b0db5283\",\n  \"id_token\": \"alice\",\n  \"token_type\": \"Bearer\"\n}",
  "headers" : {
    "Content-Type" : "application/json"
  }
}

id_token must be a JWT token - so please use the value you used for the non-opaque tests, temp print this value and use it - and use the same value for the access_token for simplicity. You can drop token_type

@sberyozkin
Copy link
Member

sberyozkin commented Mar 10, 2021

@cemnura please also resolve the conflicts - though please do it after the test is working :-)

@cemnura cemnura force-pushed the feature/oidc-wiremock-codeflow branch 2 times, most recently from 8687db9 to a972c78 Compare March 11, 2021 10:42
@sberyozkin
Copy link
Member

Hey @cemnura Yes, please note it is better to generate the tokens from the stub endpoint - or generate them at the Wiremock init time and make them last forever :-)

Base automatically changed from master to main March 12, 2021 15:55
@cemnura
Copy link
Contributor Author

cemnura commented Mar 12, 2021

@sberyozkin you were right the access token was expired long before I was even able to run the first test yet alone further iterations.

I dynamically added the access_token and id_token and rearranged the test and everything seems to be working.

There might be a few topics that we might need to discuss.

Currently, I am creating access_token and id_token for the stub such as here

getAccessToken("alice", new HashSet<>(Arrays.asList("user", "admin")))

We may need to make this dynamic according to the desired authenticated user. But how would we get the userName during the request to the token endpoint?

@sberyozkin
Copy link
Member

@cemnura This is excellent work - thanks for trying hard to make it work and actually making the test pass :-)
Good point about the user name - it is coming in the original authentication request - so I don't think you can retain till the moment when the token request arrives as it does not go via the browser so you can't even use the custom cookie to retain it...
For now I'd keep alice only - and we can revisit it in a follow up issue where we'd want to modularize this wiremock code.
There is one last thing I'd like to ask you to fix - in the test code you have an unused method which verifies the location header. I suppose for the wiremock tests we can remove it - please do it and I'll be happy to merge

thanks

@cemnura cemnura force-pushed the feature/oidc-wiremock-codeflow branch from 7d0cf6c to f987e6a Compare March 13, 2021 19:21
@cemnura
Copy link
Contributor Author

cemnura commented Mar 13, 2021

🎉 Removed unused methods and rebased 😄

@sberyozkin
Copy link
Member

@cemnura thanks, merging now - I'll ping you later about other possible issues - I might follow with a quick modularization and doc update - but there are plenty of issues there :-)

@sberyozkin sberyozkin self-requested a review March 14, 2021 12:26
@sberyozkin sberyozkin merged commit 692cbdb into quarkusio:main Mar 14, 2021
@quarkus-bot quarkus-bot bot added this to the 1.13 - master milestone Mar 14, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add OIDC integration tests which use WireMockServer
2 participants