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

OIDC extension fails with Okta OIDC #7129

Closed
moksamedia opened this issue Feb 11, 2020 · 10 comments
Closed

OIDC extension fails with Okta OIDC #7129

moksamedia opened this issue Feb 11, 2020 · 10 comments

Comments

@moksamedia
Copy link

Describe the bug
OIDC extension configured to use Okta OIDC is stuck in a redirect loop. The code is never exchanged for a token. The OIDC app configuration works with OIDC Debugger.

application.properties

quarkus.http.root-path=/kafka-client
quarkus.oidc.auth-server-url=https://dev-447850.okta.com
quarkus.oidc.client-id=<<Client ID>>
quarkus.oidc.credentials.secret=<<Client Secret>>
quarkus.oidc.authentication.scopes=openid
quarkus.oidc.application-type=web-app
quarkus.oidc.authentication.redirect-path=/kafka-client

Network redirects:

302 GET localhost:8080 secured document plain 402 B 0 B
302 GET dev-447850.okta.com authorize?redirect_uri=http://localhost:8080/kafka-client&state=27ab84bf-e2b8-4c91-af6a-0b448cd6548c&scope=openid+openid&response_type=code&client_id=0oa25vnmhPszBCA3R4x6 document plain 2.49 KB 0 B
302 GET localhost:8080 kafka-client?code=jp_7_w68G7w0UmKV61Hd&state=27ab84bf-e2b8-4c91-af6a-0b448cd6548c document plain 181 B 0 B
302 GET localhost:8080 secured?pathChecked=true&code=jp_7_w68G7w0UmKV61Hd&state=27ab84bf-e2b8-4c91-af6a-0b448cd6548c document plain 402 B 0 B
302 GET dev-447850.okta.com authorize?redirect_uri=http://localhost:8080/kafka-client&state=1f447861-ef32-4e6a-8d3d-29bc0963625f&scope=openid+openid&response_type=code&client_id=0oa25vnmhPszBCA3R4x6 document plain 2.49 KB 0 B
302 GET localhost:8080 kafka-client?code=nVqlC135IJMoFhRxR-8C&state=1f447861-ef32-4e6a-8d3d-29bc0963625f document plain 181 B 0 B
302 GET localhost:8080 secured?pathChecked=true&code=nVqlC135IJMoFhRxR-8C&state=1f447861-ef32-4e6a-8d3d-29bc0963625f document plain 402 B 0 B
302 GET dev-447850.okta.com authorize?redirect_uri=http://localhost:8080/kafka-client&state=226998f7-305f-47e9-9bf0-58e35f3652d9&scope=openid+openid&response_type=code&client_id=0oa25vnmhPszBCA3R4x6 document plain 2.49 KB 0 B
302 GET localhost:8080 kafka-client?code=SOe9kOCCfwtnuBcfsOYX&state=226998f7-305f-47e9-9bf0-58e35f3652d9 document plain 181 B 0 B

Environment (please complete the following information):

  • Output of uname -a or ver:
    Linux pop-os 5.3.0-7625-generic Modify BeanArchiveProcessor so that implicit bean archives are added to #27157677456019.10~f432cd8-Ubuntu SMP Thu Dec 19 20:35:37 UTC x86_64 x86_64 x86_64 GNU/Linux
  • Output of java -version:
    openjdk version "11.0.5" 2019-10-15
    OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.5+10)
    Eclipse OpenJ9 VM AdoptOpenJDK (build openj9-0.17.0, JRE 11 Linux amd64-64-Bit Compressed References 20191016_358 (JIT enabled, AOT enabled)
    OpenJ9 - 77c1cf708
    OMR - 20db4fbc
    JCL - 2a7af5674b based on jdk-11.0.5+10)
  • GraalVM version (if different from Java):
  • Quarkus version or git rev:

Additional context
Project created with this command:

mvn io.quarkus:quarkus-maven-plugin:1.2.0.Final:create \
	-DprojectGroupId=com.okta \
	-DprojectArtifactId=quarkus-client \
        -DclassName="com.okta.quarkusclient.SecureResource" \
	-Dextensions="quarkus-smallrye-reactive-messaging-kafka, oidc"

One resource:

package com.okta.quarkusclient;

import javax.annotation.security.RolesAllowed;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/secured")
@RolesAllowed({"Everyone"})
public class SecureResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}
@moksamedia moksamedia added the kind/bug Something isn't working label Feb 11, 2020
@moksamedia
Copy link
Author

moksamedia commented Feb 11, 2020

A little more info, debugging CodeAuthenticationMechanism reveals this error:

Unauthorized: {"error":"invalid_request","error_description":"Cannot supply multiple client credentials. Use one of the following: credentials in the Authorization header, credentials in the post body, or a client_assertion in the post body."}

@gsmet
Copy link
Member

gsmet commented Feb 11, 2020

/cc @sberyozkin @pedroigor

@sberyozkin
Copy link
Member

@moksamedia Hi, thanks for the thorough analysis, I believe it has been fixed with Quarkus https://github.com/quarkusio/quarkus/tree/1.3.0.Alpha1, can you please try it ?

@moksamedia
Copy link
Author

moksamedia commented Feb 11, 2020

@sberyozkin That does work, thanks.

For posterity, here are the application.properties settings I used. I had to change the Okta auth server URL from https://dev-447850.okta.com to https://dev-447850.okta.com/oauth2/default.

quarkus.http.root-path=/kafka-client
quarkus.oidc.auth-server-url=https://dev-447850.okta.com/oauth2/default
quarkus.oidc.client-id={cliendId}
quarkus.oidc.credentials.secret={cliendSecret}
quarkus.oidc.authentication.scopes=openid,profile
quarkus.oidc.application-type=web-app
quarkus.oidc.authentication.redirect-path=/kafka-client

This is using Role-based auth on a /kafka-client/secured endpoint.

@Path("/secured")
@RolesAllowed({"Everyone"})
public class SecureResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

@moksamedia
Copy link
Author

moksamedia commented Feb 11, 2020

@sberyozkin Two questions:

  1. when is 1.3.0 expected to be released?
  2. I saw that this was covered in another ticked, but are you planning on updating the redirect_uri parameter so that it can be a static URL that's not a child of the request URI? Something more like /oauth/callback instead of the app base URL? Seems like a strange way to do that.

@sberyozkin
Copy link
Member

sberyozkin commented Feb 12, 2020

@moksamedia Thanks for the update.
Did you have to change the Okta endpoint address because it was not responding to the discovery request ? Then indeed, changing the address is required. The alternative option is to keep the original address but to use introspection-path and jwks-path properties though we actually haven't had any confirmation from the users they work.

Can you please check if the alternative option works and update #5827 if not ?

when is 1.3.0 expected to be released?

I don't know, hopefully soon enough.

I saw that this was covered in another ticked, but are you planning on updating the redirect_uri parameter so that it can be a static URL that's not a child of the request URI? Something more like /oauth/callback instead of the app base URL? Seems like a strange way to do that.

Nonetheless it worked for some users, and it really depends on the way the protected application interacts with the users. The primary purpose was to ensure the clients can be whitelisted based on the specific redirect URI value as asked by Aaron.
But yes it was too restrictive. A new restore-path-after-redirect property is now available and if set to false then the user would be returned to whatever redirect-path relative property is set.

Hope it helps, I'd like to close this issue soon, likely tomorrow due to a time difference

@moksamedia
Copy link
Author

I only added the thing about changing the Okta endpoint so that if someone else found this trying to figure things out, they'd have correct info. It was my mistake. I don't think it's a problem with the OIDC extension. I'll close the ticket.

@gsmet gsmet modified the milestones: 1.3.0, 1.3.0.Alpha1 Feb 16, 2020
@brahimk
Copy link

brahimk commented Feb 28, 2020

Hey @moksamedia @gsmet

I'am testing the 1.3.0.Alpha2 version with oidc security dependency.

When I enter the login/Password, i have the same behaviour with cyclic 302 between the Auth Server SSO (forgerock) and my front, and at the end nothing is displayed.

image

My config properties :

quarkus.oidc.auth-server-url=https://sso-XXXXXXXXXXXX/oauth2/preprod quarkus.oidc.client-id=XXXXXXXXXXXXXXX quarkus.oidc.application-type=web-app quarkus.http.auth.permission.authenticated.paths=/* quarkus.http.auth.permission.authenticated.policy=authenticated quarkus.oidc.introspection-path=/.well-known/openid-configuration quarkus.oidc.authentication.scopes=openid,profile,email quarkus.oidc.authentication.redirect-path=/login/oauth2/code/oidc quarkus.http.cors=true quarkus.oidc.credentials.secret=XXXXXXXXXXXXXXXXXX

Another thing, that i could not explain, is if I put a breakPoint on line 186 io.quarkus.oidc.runtime.CodeAuthenticationMechanism.java and after the login a wait 3 sec. All are ok and the cyclic behaviour disappears.

image

And in log, i have this :

2020-02-28 01:41:32,076 WARNING [io.ver.cor.imp.BlockedThreadChecker] (vertx-blocked-thread-checker) Thread Thread[vert.x-eventloop-thread-1,5,main]=Thread[vert.x-eventloop-thread-1,5,main] has been blocked for 3002 ms, time limit is 2000 ms: io.vertx.core.VertxException: Thread blocked
at io.quarkus.oidc.runtime.CodeAuthenticationMechanism.lambda$performCodeFlow$1(CodeAuthenticationMechanism.java:186)
at io.quarkus.oidc.runtime.CodeAuthenticationMechanism$$Lambda$584/0x00000008006a7840.handle(Unknown Source)
at io.vertx.ext.auth.oauth2.impl.OAuth2AuthProviderImpl.lambda$authenticate$2(OAuth2AuthProviderImpl.java:249)
at io.vertx.ext.auth.oauth2.impl.OAuth2AuthProviderImpl$$Lambda$585/0x00000008006a7c40.handle(Unknown Source)
at io.vertx.ext.auth.oauth2.impl.flow.AuthCodeImpl.lambda$getToken$0(AuthCodeImpl.java:93)
at io.vertx.ext.auth.oauth2.impl.flow.AuthCodeImpl$$Lambda$586/0x00000008006a7040.handle(Unknown Source)
at io.vertx.ext.auth.oauth2.impl.flow.AbstractOAuth2Flow.lambda$getToken$0(AbstractOAuth2Flow.java:148)
at io.vertx.ext.auth.oauth2.impl.flow.AbstractOAuth2Flow$$Lambda$587/0x00000008006a7440.handle(Unknown Source)
at io.vertx.ext.auth.oauth2.impl.OAuth2API.lambda$null$1(OAuth2API.java:129)
at io.vertx.ext.auth.oauth2.impl.OAuth2API$$Lambda$522/0x00000008005c9c40.handle(Unknown Source)
at io.vertx.core.http.impl.HttpClientResponseImpl$BodyHandler.notifyHandler(HttpClientResponseImpl.java:292)
at io.vertx.core.http.impl.HttpClientResponseImpl.lambda$bodyHandler$0(HttpClientResponseImpl.java:193)
at io.vertx.core.http.impl.HttpClientResponseImpl$$Lambda$523/0x0000000800640040.handle(Unknown Source)
at io.vertx.core.http.impl.HttpClientResponseImpl.handleEnd(HttpClientResponseImpl.java:248)
at io.vertx.core.http.impl.Http1xClientConnection$StreamImpl.lambda$beginResponse$0(Http1xClientConnection.java:480)
at io.vertx.core.http.impl.Http1xClientConnection$StreamImpl$$Lambda$519/0x00000008005ca040.handle(Unknown Source)
at io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:237)
at io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:127)
at io.vertx.core.http.impl.Http1xClientConnection$StreamImpl.endResponse(Http1xClientConnection.java:499)
at io.vertx.core.http.impl.Http1xClientConnection$StreamImpl.access$000(Http1xClientConnection.java:237)
at io.vertx.core.http.impl.Http1xClientConnection.handleResponseEnd(Http1xClientConnection.java:634)
at io.vertx.core.http.impl.Http1xClientConnection.handleHttpMessage(Http1xClientConnection.java:584)
at io.vertx.core.http.impl.Http1xClientConnection.handleMessage(Http1xClientConnection.java:566)
at io.vertx.core.net.impl.VertxHandler$$Lambda$517/0x00000008005cb440.handle(Unknown Source)
at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:369)
at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:43)
at io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:232)
at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:173)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:316)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1470)
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1219)
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1266)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:493)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:432)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:271)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:355)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:377)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:363)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
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 [email protected]/java.lang.Thread.run(Thread.java:834)

Do you have a solution for me please ?

Thanks.

@mraible
Copy link

mraible commented Mar 10, 2020

I'm still having an issue getting the OIDC client to work with Okta. I'm using 1.3.0.CR2. I created an app using the following command:

mvn io.quarkus:quarkus-maven-plugin:1.3.0.CR2:create \
-DplatformVersion=1.3.0.CR2 -DplatformArtifactId=quarkus-bom \
-DprojectGroupId=com.okta -DprojectArtifactId=quarkus-client \
-DclassName="com.okta.quarkusclient.SecureResource" \
-Dextensions="quarkus-smallrye-reactive-messaging-kafka,oidc,quarkus-resteasy-qute"

Then I created a "Web" app on Okta and set the login redirect URI to be http://localhost:8080. I copy/pasted the settings into application.properties:

quarkus.oidc.auth-server-url=https://{OktaDomain}/oauth2/default
quarkus.oidc.client-id={ClientId}
quarkus.oidc.credentials.secret={ClientSecret}
quarkus.oidc.authentication.scopes=openid,profile
quarkus.oidc.application-type=web-app
quarkus.oidc.authentication.redirect-path=/
quarkus.oidc.cookie-path=/

It redirects me to log in successfully, but when it comes back to the app, it gives me a 401.

Screen Shot 2020-03-10 at 10 38 28 AM

@brahimk
Copy link

brahimk commented Apr 9, 2020

@mraible I have the same problem.

I specified the redirect-path but when it's called this url don't have the HTTPS protocol.
It is the good url but without the S of https.

My configuration :
quarkus.oidc.auth-server-url=https://MYURL
quarkus.oidc.application-type=web-app
quarkus.oidc.introspection-path=/.well-known/openid-configuration
quarkus.oidc.authentication.scopes=profile,email,myroles
quarkus.oidc.authentication.redirect-path=/login/oauth2/code/oidc
quarkus.http.cors=true
quarkus.oidc.authentication.restore-path-after-redirect=true
quarkus.oidc.credentials.client-secret.method=post
quarkus.oidc.credentials.client-secret.value={ClientSecret}
quarkus.oidc.client-id={ClientId}

The location in request is :_
https://MYURL/authorize?redirect_uri=http%3A%2F%2Fmysample.toto.fr%2Flogin%2Foauth2%2Fcode%2Foidc

Expected location is :
https://MYURL/authorize?redirect_uri=https%3A%2F%2Fmysample.toto.fr%2Flogin%2Foauth2%2Fcode%2Foidc

Do you have a solution for me please?

I use 1.3.1.Final Quarkus version.

Thanks.

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

No branches or pull requests

5 participants