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 code flow fails when Auth0 returns a binary access token #8396

Closed
majonga88 opened this issue Apr 5, 2020 · 13 comments · Fixed by #10417
Closed

OIDC code flow fails when Auth0 returns a binary access token #8396

majonga88 opened this issue Apr 5, 2020 · 13 comments · Fixed by #10417
Assignees
Labels
area/oidc kind/question Further information is requested
Milestone

Comments

@majonga88
Copy link

majonga88 commented Apr 5, 2020

Hello guys,

I'm trying to securized one of my endpoints with scopes via Auth0 provider. The connection with Oauth provider working but i cannot able to put scope management into my api with quarkus.

I compare the js solution which is working and quarkus solution which i have an issue.

In JS sample provided by Auth0

Following this tutorial, the scopes are managed like this :

// Middleware to check scopes
const checkPermissions = function(req, res, next){
  switch(req.path){
    case '/api/contacts':{
      var permissions = ['read:contacts'];
      for(var i = 0; i < permissions.length; i++){
        if(req.user.scope.includes(permissions[i])){
          next();
        } else {
          res.status(403).send({message:'Forbidden'});
        }
      }
      break;
    }
  }
}

Source

In Quarkus sample i've made

Do you have a similar thing in Quarkus side ? Because i used this property quarkus.oidc.authentication.scopes and it's not working, i don't have any check to forbidden the access if i remove read:contacts scope for example.

Source

I have this error stack when i trying to connect to my api. Maybe is the cause of not working ?

2020-04-05 11:47:24,915 DEBUG [io.qua.res.runtime] (main) Create constructor: public org.jboss.resteasy.plugins.interceptors.MessageSanitizerContainerResponseFilter()
2020-04-05 11:47:24,915 DEBUG [io.qua.arc.run.ArcRecorder] (main) No matching bean found for type class org.jboss.resteasy.plugins.interceptors.MessageSanitizerContainerResponseFilter and
qualifiers []. The bean might have been marked as unused and removed during build.
2020-04-05 11:47:24,917 DEBUG [io.qua.res.runtime] (main) Create resource constructor: public org.acme.security.openid.connect.SecuredResource()
2020-04-05 11:47:24,917 DEBUG [io.qua.res.runtime] (main) Create resource constructor: public org.acme.security.openid.connect.AdminResource()
2020-04-05 11:47:24,917 DEBUG [io.qua.res.runtime] (main) Create resource constructor: public org.acme.security.openid.connect.AdminResource()
2020-04-05 11:47:24,965 DEBUG [io.net.uti.int.log.InternalLoggerFactory] (Thread-26) Using SLF4J as the default logging framework
2020-04-05 11:47:24,968 DEBUG [org.jbo.threads] (main) JBoss Threads version 3.0.1.Final
2020-04-05 11:47:24,968 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) -Dio.netty.noUnsafe: false
2020-04-05 11:47:24,968 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) Java version: 8
2020-04-05 11:47:24,968 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) sun.misc.Unsafe.theUnsafe: available
2020-04-05 11:47:24,969 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) sun.misc.Unsafe.copyMemory: available
2020-04-05 11:47:24,969 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) java.nio.Buffer.address: available
2020-04-05 11:47:24,969 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) direct buffer constructor: available
2020-04-05 11:47:24,970 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) java.nio.Bits.unaligned: available, true
2020-04-05 11:47:24,970 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) jdk.internal.misc.Unsafe.allocateUninitializedArray(int): unavailable prior to Java9
2020-04-05 11:47:24,970 DEBUG [io.net.uti.int.PlatformDependent0] (Thread-26) java.nio.DirectByteBuffer.<init>(long, int): available
2020-04-05 11:47:24,970 DEBUG [io.net.uti.int.PlatformDependent] (Thread-26) sun.misc.Unsafe: available
2020-04-05 11:47:24,970 DEBUG [io.net.uti.int.PlatformDependent] (Thread-26) -Dio.netty.tmpdir: /tmp (java.io.tmpdir)
2020-04-05 11:47:24,970 DEBUG [io.net.uti.int.PlatformDependent] (Thread-26) -Dio.netty.bitMode: 64 (sun.arch.data.model)
2020-04-05 11:47:24,971 DEBUG [io.net.uti.int.PlatformDependent] (Thread-26) -Dio.netty.maxDirectMemory: 3797417984 bytes
2020-04-05 11:47:24,971 DEBUG [io.net.uti.int.PlatformDependent] (Thread-26) -Dio.netty.uninitializedArrayAllocationThreshold: -1
2020-04-05 11:47:24,971 DEBUG [io.net.uti.int.CleanerJava6] (Thread-26) java.nio.ByteBuffer.cleaner(): available
2020-04-05 11:47:24,971 DEBUG [io.net.uti.int.PlatformDependent] (Thread-26) -Dio.netty.noPreferDirect: false
2020-04-05 11:47:24,974 DEBUG [io.net.cha.DefaultChannelId] (Thread-26) -Dio.netty.processId: 4030 (auto-detected)
2020-04-05 11:47:24,975 DEBUG [io.net.uti.NetUtil] (Thread-26) -Djava.net.preferIPv4Stack: false
2020-04-05 11:47:24,975 DEBUG [io.net.uti.NetUtil] (Thread-26) -Djava.net.preferIPv6Addresses: false
2020-04-05 11:47:24,978 DEBUG [io.net.uti.NetUtil] (Thread-26) Loopback interface: lo (lo, 0:0:0:0:0:0:0:1%lo)
2020-04-05 11:47:24,978 DEBUG [io.net.uti.NetUtil] (Thread-26) /proc/sys/net/core/somaxconn: 128
2020-04-05 11:47:24,979 DEBUG [io.net.cha.DefaultChannelId] (Thread-26) -Dio.netty.machineId: cc:b0:da:ff:fe:8c:69:57 (auto-detected)
2020-04-05 11:47:25,636 DEBUG [io.net.uti.ResourceLeakDetector] (main) -Dio.netty.leakDetection.level: simple
2020-04-05 11:47:25,637 DEBUG [io.net.uti.ResourceLeakDetector] (main) -Dio.netty.leakDetection.targetRecords: 4
2020-04-05 11:47:25,640 DEBUG [io.net.uti.int.InternalThreadLocalMap] (main) -Dio.netty.threadLocalMap.stringBuilder.initialSize: 1024
2020-04-05 11:47:25,641 DEBUG [io.net.uti.int.InternalThreadLocalMap] (main) -Dio.netty.threadLocalMap.stringBuilder.maxSize: 4096
2020-04-05 11:47:25,667 DEBUG [io.net.cha.MultithreadEventLoopGroup] (main) -Dio.netty.eventLoopThreads: 24
2020-04-05 11:47:25,681 DEBUG [io.net.cha.nio.NioEventLoop] (main) -Dio.netty.noKeySetOptimization: false
2020-04-05 11:47:25,681 DEBUG [io.net.cha.nio.NioEventLoop] (main) -Dio.netty.selectorAutoRebuildThreshold: 512
2020-04-05 11:47:25,683 DEBUG [io.net.uti.int.PlatformDependent] (main) org.jctools-core.MpscChunkedArrayQueue: available
2020-04-05 11:47:25,704 DEBUG [io.qua.ver.cor.run.VertxCoreRecorder] (main) Vertx has Native Transport Enabled: false
2020-04-05 11:47:25,813 DEBUG [io.net.han.ssl.JdkSslContext] (main) Default protocols (JDK): [TLSv1.2, TLSv1.1, TLSv1] 
2020-04-05 11:47:25,813 DEBUG [io.net.han.ssl.JdkSslContext] (main) Default cipher suites (JDK): [TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH
E_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_
AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA]
2020-04-05 11:47:25,850 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.numHeapArenas: 24
2020-04-05
 11:47:25,851 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.numDirectArenas: 24
2020-04-05 11:47:25,851 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.pageSize: 8192
2020-04-05 11:47:25,851 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.maxOrder: 1
2020-04-05 11:47:25,852 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.chunkSize: 16384
2020-04-05 11:47:25,852 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.tinyCacheSize: 512
2020-04-05 11:47:25,852 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.smallCacheSize: 256
2020-04-05 11:47:25,852 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.normalCacheSize: 64
2020-04-05 11:47:25,853 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.maxCachedBufferCapacity: 32768
2020-04-05 11:47:25,853 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.cacheTrimInterval: 8192
2020-04-05 11:47:25,853 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.cacheTrimIntervalMillis: 0
2020-04-05 11:47:25,854 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.useCacheForAllThreads: true
2020-04-05 11:47:25,854 DEBUG [io.net.buf.PooledByteBufAllocator] (vert.x-eventloop-thread-2) -Dio.netty.allocator.maxCachedByteBuffersPerChunk: 1023
2020-04-05 11:47:25,880 DEBUG [io.net.buf.ByteBufUtil] (vert.x-eventloop-thread-2) -Dio.netty.allocator.type: pooled
2020-04-05 11:47:25,880 DEBUG [io.net.buf.ByteBufUtil] (vert.x-eventloop-thread-2) -Dio.netty.threadLocalDirectBufferSize: 0
2020-04-05 11:47:25,880 DEBUG [io.net.buf.ByteBufUtil] (vert.x-eventloop-thread-2) -Dio.netty.maxThreadLocalCharBufferSize: 16384
2020-04-05 11:47:26,119 DEBUG [io.net.buf.AbstractByteBuf] (vert.x-eventloop-thread-2) -Dio.netty.buffer.checkAccessible: true
2020-04-05 11:47:26,121 DEBUG [io.net.buf.AbstractByteBuf] (vert.x-eventloop-thread-2) -Dio.netty.buffer.checkBounds: true
2020-04-05 11:47:26,134 DEBUG [io.net.uti.ResourceLeakDetectorFactory] (vert.x-eventloop-thread-2) Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@81f077
2020-04-05 11:47:26,138 DEBUG [io.net.uti.Recycler] (vert.x-eventloop-thread-2) -Dio.netty.recycler.maxCapacityPerThread: 4096
2020-04-05 11:47:26,139 DEBUG [io.net.uti.Recycler] (vert.x-eventloop-thread-2) -Dio.netty.recycler.maxSharedCapacityFactor: 2
2020-04-05 11:47:26,139 DEBUG [io.net.uti.Recycler] (vert.x-eventloop-thread-2) -Dio.netty.recycler.linkCapacity: 16
2020-04-05 11:47:26,139 DEBUG [io.net.uti.Recycler] (vert.x-eventloop-thread-2) -Dio.netty.recycler.ratio: 8
2020-04-05 11:47:26,553 DEBUG [io.net.han.ssl.SslHandler] (vert.x-eventloop-thread-2) [id: 0xc1c4a70b, L:/192.168.1.16:65168 - R:dev-0-77r6yl.auth0.com/52.41.33.6:443] HANDSHAKEN: TLS_ECDH
E_RSA_WITH_AES_128_GCM_SHA256
2020-04-05 11:47:26,780 FINE  [io.ver.ext.aut.oau.imp.OAuth2ResponseImpl] (vert.x-eventloop-thread-2) New response: statusCode: 200
2020-04-05 11:47:26,915 FINE  [io.ver.ext.aut.oau.imp.OAuth2API] (vert.x-eventloop-thread-2) Fetching URL: https://dev-0-77r6yl.auth0.com/.well-known/jwks.json
2020-04-05 11:47:27,439 DEBUG [io.net.han.ssl.SslHandler] (vert.x-eventloop-thread-2) [id: 0x46d49200, L:/192.168.1.16:65187 - R:dev-0-77r6yl.auth0.com/52.41.33.6:443] HANDSHAKEN: TLS_ECDH
E_RSA_WITH_AES_128_GCM_SHA256
2020-04-05 11:47:27,616 FINE  [io.ver.ext.aut.oau.imp.OAuth2ResponseImpl] (vert.x-eventloop-thread-2) New response: statusCode: 200
2020-04-05 11:47:27,682 INFO  [io.quarkus] (main) security-openid-connect-quickstart 1.0-SNAPSHOT (powered by Quarkus 1.3.1.Final) started in 4.187s. Listening on: http://0.0.0.0:8080
2020-04-05 11:47:27,683 INFO  [io.quarkus] (main) Profile dev activated. Live Coding activated.
2020-04-05 11:47:27,684 INFO  [io.quarkus] (main) Installed features: [cdi, oidc, resteasy, resteasy-jsonb, security]
2020-04-05 11:53:58,027 DEBUG [io.net.han.cod.com.ZlibCodecFactory] (vert.x-eventloop-thread-4) -Dio.netty.noJdkZlibDecoder: false
2020-04-05 11:53:58,028 DEBUG [io.net.han.cod.com.ZlibCodecFactory] (vert.x-eventloop-thread-4) -Dio.netty.noJdkZlibEncoder: false
2020-04-05 11:53:58,078 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (vert.x-eventloop-thread-4) Authentication request redirect_uri parameter: http://beyondthegates:8080/
2020-04-05 11:54:36,177 DEBUG [io.qua.oid.run.CodeAuthenticationMechanism] (vert.x-eventloop-thread-4) Token request redirect_uri parameter: http://beyondthegates:8080/
2020-04-05 11:54:36,179 FINE  [io.ver.ext.aut.oau.imp.OAuth2API] (vert.x-eventloop-thread-4) Fetching URL: https://dev-0-77r6yl.auth0.com/oauth/token
2020-04-05 11:54:36,735 DEBUG [io.net.han.ssl.SslHandler] (vert.x-eventloop-thread-4) [id: 0xce6e641f, L:/192.168.1.16:65533 - R:dev-0-77r6yl.auth0.com/54.187.48.79:443] HANDSHAKEN: TLS_EC
DHE_RSA_WITH_AES_128_GCM_SHA256
2020-04-05 11:54:36,937 FINE  [io.ver.ext.aut.oau.imp.OAuth2ResponseImpl] (vert.x-eventloop-thread-4) New response: statusCode: 200
2020-04-05 11:54:36,942 FINE  [io.ver.ext.aut.oau.imp.OAuth2UserImpl] (vert.x-eventloop-thread-4) Cannot decode token:: java.lang.RuntimeException: Not enough or too many segments
        at io.vertx.ext.jwt.JWT.decode(JWT.java:259)
        at io.vertx.ext.auth.oauth2.impl.OAuth2UserImpl.decodeToken(OAuth2UserImpl.java:173)
        at io.vertx.ext.auth.oauth2.impl.OAuth2UserImpl.decodeToken(OAuth2UserImpl.java:147)
        at io.vertx.ext.auth.oauth2.impl.OAuth2UserImpl.init(OAuth2UserImpl.java:64)
        at io.vertx.ext.auth.oauth2.impl.OAuth2UserImpl.setAuthProvider(OAuth2UserImpl.java:91)
        at io.vertx.ext.auth.oauth2.impl.OAuth2UserImpl.<init>(OAuth2UserImpl.java:40)
        at io.vertx.ext.auth.oauth2.impl.OAuth2TokenImpl.<init>(OAuth2TokenImpl.java:55)
        at io.vertx.ext.auth.oauth2.impl.flow.AuthCodeImpl.lambda$getToken$0(AuthCodeImpl.java:87)
        at io.vertx.ext.auth.oauth2.impl.flow.AbstractOAuth2Flow.lambda$getToken$0(AbstractOAuth2Flow.java:148)
        at io.vertx.ext.auth.oauth2.impl.OAuth2API.lambda$null$1(OAuth2API.java:129)
        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.handleEnd(HttpClientResponseImpl.java:248)
        at io.vertx.core.http.impl.Http1xClientConnection$StreamImpl.lambda$beginResponse$0(Http1xClientConnection.java:480)
        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.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:321)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:295)
        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:498)
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:437)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
        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 java.lang.Thread.run(Thread.java:748)

2020-04-05 11:54:37,270 DEBUG [org.jbo.res.res.i18n] (executor-thread-1) RESTEASY002315: PathInfo: /favicon.ico
2020-04-05 11:54:37,285 DEBUG [org.jbo.res.res.i18n] (executor-thread-1) {image/webp=org.jboss.resteasy.core.request.QualityValue@3e8, image/apng=org.jboss.resteasy.core.request.QualityVal
ue@3e8, image/*=org.jboss.resteasy.core.request.QualityValue@3e8, */*=org.jboss.resteasy.core.request.QualityValue@320}

Expected behavior
When i remove scope permission from Auth0 interface, forbidden access to my endpoint.

Actual behavior
The scope doesn't checked by the application.

Thanks a lot, for your help.

@majonga88 majonga88 added the kind/question Further information is requested label Apr 5, 2020
@majonga88 majonga88 changed the title OIDC Scopes not supported well for Auth0 ? OIDC scopes not supported well for Auth0 ? Apr 5, 2020
@sberyozkin
Copy link
Member

@majonga88 Hi, quarkus.oidc.role-claim-path=scope will get a scope claim checked.

quarkus.oidc.authentication.scopes is about configuring quarkus-oidc to request that a token which will be obtained as part of the code flow should get these scopes.

The debug message you are seeing seem to confirm that Auth0 returns an opaque token (not JWT) so Vertx asks Auth0 to introspect it.

Try the above property please

@majonga88
Copy link
Author

Hello,

Thank you to reply me, I try this configuration :

quarkus.oidc.auth-server-url=https://dev-0-77r6yl.auth0.com
quarkus.oidc.authentication.redirect-path=/
quarkus.oidc.application-type=web-app
quarkus.oidc.client-id=XXXX
quarkus.oidc.credentials.secret=XXXX
quarkus.oidc.authentication.scopes=read:contacts
quarkus.oidc.role-claim-path=scope
quarkus.http.auth.permission.authenticated.paths=/*
quarkus.http.auth.permission.authenticated.policy=authenticated

quarkus.log.level=DEBUG

But i have the same issue, the scope is not checked, and i have this error again :

java.lang.RuntimeException: Not enough or too many segments

If you want to try my source feel free to ask the clientId and secrets.

@sberyozkin
Copy link
Member

@majonga88 OK, the problem seems to do with the fact that Auth0 returns a binary (non-JWT) access token as part of the code flow. Vertx does have some code where it tries to introspect such binary tokens but only when such a token is already provided to quarkus-oidc as a bearer token (there is an issue to verify it). But in your case it is a code flow. I don't see any workaround but to update Vertx to return such a binary token directly to Quarkus if requested.
I'm sorry but it will take awhile as we need to apply few fixes to Vertx OAuth2 and it will need to be released. I'll assign to myself

@sberyozkin sberyozkin self-assigned this Apr 6, 2020
@sberyozkin sberyozkin changed the title OIDC scopes not supported well for Auth0 ? OIDC code flow fails when Auth0 returns a binary access token Apr 6, 2020
@majonga88
Copy link
Author

@sberyozkin I will be patient :), if you want client-id and secret please contact me in pm, i really enjoy what you're doing guys ! Thank you !

@sberyozkin
Copy link
Member

@majonga88 Thanks; in meantime perhaps you can configure Auth0 to send JWT token instead ?

According to this doc, Auth0 can return the binary token, and I've read somewhere else that it may return the binary tokens in all cases on the so called legacy pipelines. If you can make it return JWT it will work, I believe we've had the users confirming they could use Auth0

@majonga88
Copy link
Author

majonga88 commented Apr 7, 2020

@sberyozkin Indeed, but you have to handle JWT generation inside your front end application here an example and i don't want to. I want to have authentification/authorization flow outside my applications (back and front). I know it's a step to unlock the problem, but i prefer wait a proper solution on your side.

@sberyozkin
Copy link
Member

@majonga88 Can you please explain more what is happening ? We are looking at the Vertx code with @pmlopes and indeed when the binary access token is verified, the exception which you in the trace logs is thrown but the execution should still continue.
What happens if you have no RolesAllowed annotation and only @Authenticated annotation ?

@pmlopes
Copy link
Contributor

pmlopes commented May 8, 2020

It seems you have a logging bug on quarkus side, as you can see the level of those messages is FINE (which lower than DEBUG) and you configured it as DEBUG and they still show up. So somewhere the logging framework is wrong. Vert.x doesn't include any loggers so the level is not configured correctly somewhere else.

@sberyozkin
Copy link
Member

sberyozkin commented May 11, 2020

@pmlopes The logging issue is really an orthogonal issue. The users may not even know what format the AT is in. The point is, in the code flow, we don't use it at all, we only use an ID token. From Auth0 docs (we did not use those docs as a foundation, but FYI as it is inline with what Quarkus does in the code flow):

Remember that an Access Token is meant for an API and should be validated only by the API for which it was intended. Client applications should not depend on the Access Token to be any specific format, and instead treat it as if it is opaque (regardless of whether it actually is).

We may need to allow treating the access tokens as if they were intended for this client application (this Quarkus endpoint which runs the code flow) as I guess in some cases the borders between id and access tokens can be vague. But that is a separate issue.

So @majonga88 can you please do the following:

@Authenticated
@Path("service")
public class MyResource {
   @Inject 
   @IdToken    
   JsonWebToken idToken;

  @GET
  public String getPermissions() {
      // or return all the claims by iterating with idToken.getClaimNames() 
      return idToken.getClaim("permissions");
  }
}

I'd like to see if the IdToken contains anything related to the permissions at all.
If it does not then it is likely that, given that AT is opaque, we may need to use it to ping the Auth0 UserInfo endpoint.

Give it a try and let me know what you find, I'll then proceed with a fix as needed

@majonga88
Copy link
Author

majonga88 commented May 11, 2020

Hello @sberyozkin,

I'm sorry to reply lately. I trying to get permissions with your code, but i don't have this information.

Screenshot 2020-05-11 at 17 33 21

However, i set correctly in Auth0, the permission to my user like this :

Screenshot 2020-05-11 at 17 34 40

With idToken.getClaim("permissions"), i must see my permission which is : read:calendar

Big thank you to investigate in this.

@sberyozkin
Copy link
Member

@majonga88 Np, thanks for a quick test.
So there is nothing in the id token. And the access token is opaque. Introspecting it remotely won't give any details but the status of the token plus few more properties.
So now the only way seems to be to do a user info request using this opaque access token.
I'll investigate, cheers

@majonga88
Copy link
Author

Ok thanks a lot.

@sberyozkin
Copy link
Member

sberyozkin commented Jul 8, 2020

@majonga88 Hi, #10417 will resolve this issue.
So, to summarize, you have Auth0 returning ID token without any claims containing the roles, and an opaque access token. To get the roles, you could try (once the fix is merged) either quarkus.oidc.roles.source=accesstoken (this will lead to the opaque token being introspected and if it contains scope then the scope value will be used to parse the roles) or quarkus.oidc.roles.source=userinfo (in this case this opaque token will be used to fetch the UserInfo JSON which may contain the roles - but you'll likely need to add quarkus.oidc.roles.role-claim-path to name the claim which contains the roles).
In any case, all that can be done on the Quarkus side is now supported, thanks

CC @pedroigor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/oidc kind/question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants