You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tinkerpop.apache.org by "stephen mallette (JIRA)" <ji...@apache.org> on 2015/10/02 17:48:27 UTC

[jira] [Updated] (TINKERPOP3-865) Errors with HTTP REST basic auth

     [ https://issues.apache.org/jira/browse/TINKERPOP3-865?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

stephen mallette updated TINKERPOP3-865:
----------------------------------------
    Fix Version/s: 3.0.2-incubating

The REST interface probably needs some work, so I'm glad you dug into it.  It was added as a bit of an afterthought to websockets so if you have other ways of making it better or more efficient, the let's discuss.  

Glad you did this work against the tp30 branch as it would be nice to see this fix for 3.0.2. 

> Errors with HTTP REST basic auth
> --------------------------------
>
>                 Key: TINKERPOP3-865
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP3-865
>             Project: TinkerPop 3
>          Issue Type: Bug
>          Components: server
>    Affects Versions: 3.0.1-incubating
>            Reporter: Jason Plurad
>            Assignee: stephen mallette
>             Fix For: 3.0.2-incubating
>
>
> Errors with HTTP REST basic auth. I was able to reproduce this on tp30 and master. I have a pull request coming.
> 1. Built the latest tp30 branch. Copied gremlin-server-secure.yaml to gremlin-server-secure-rest.yaml and updated the channelizer to org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer.
> Ran this command.
> {noformat}
> $ curl -k -X POST -v -H 'Content-Type: application/json' -u stephen:password https://127.0.0.1:8182 -d '{"gremlin":"100-3"}'
> * Rebuilt URL to: https://127.0.0.1:8182/
> *   Trying 127.0.0.1...
> * Connected to 127.0.0.1 (127.0.0.1) port 8182 (#0)
> * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
> * Server certificate: example.com
> * Server auth using Basic with user 'stephen'
> > POST / HTTP/1.1
> > Host: 127.0.0.1:8182
> > Authorization: Basic c3RlcGhlbjpwYXNzd29yZA==
> > User-Agent: curl/7.43.0
> > Accept: */*
> > Content-Type: application/json
> > Content-Length: 19
> >
> * upload completely sent off: 19 out of 19 bytes
> {noformat}
> Got this output on the server.
> {noformat}
> [ERROR] HttpGremlinEndpointHandler - Error processing HTTP Request
> java.lang.IllegalArgumentException: Illegal base64 character 20
>     at java.util.Base64$Decoder.decode0(Base64.java:714)
>     at java.util.Base64$Decoder.decode(Base64.java:526)
>     at java.util.Base64$Decoder.decode(Base64.java:549)
>     at org.apache.tinkerpop.gremlin.server.handler.HttpBasicAuthenticationHandler.channelRead(HttpBasicAuthenticationHandler.java:64)
>     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
>     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
>     at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
>     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
>     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
>     at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:244)
>     at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:147)
>     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
>     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
>     at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1069)
>     at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:944)
>     at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:327)
>     at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:230)
>     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
>     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
>     at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)
>     at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
>     at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
>     at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
>     at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
>     at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
>     at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:111)
>     at java.lang.Thread.run(Thread.java:745)
> {noformat}
> The fix is to chop off "Basic " from the Authorization header.
> 2. After that worked, I ran into this error when trying to run consecutive curls.
> {noformat}
> $ curl -k -X POST -v -H 'Content-Type: application/json' -u stephen:password https://127.0.0.1:8182 -d '{"gremlin":"100-3"}'
> * Rebuilt URL to: https://127.0.0.1:8182/
> *   Trying 127.0.0.1...
> * Connected to 127.0.0.1 (127.0.0.1) port 8182 (#0)
> * Server aborted the SSL handshake
> * Closing connection 0
> curl: (35) Server aborted the SSL handshake
> {noformat}
> Got this output on the server.
> {noformat}
> io.netty.channel.ChannelPipelineException: org.apache.tinkerpop.gremlin.server.handler.HttpBasicAuthenticationHandler is not a @Sharable handler, so can't be added or removed multiple times.
>     at io.netty.channel.DefaultChannelPipeline.checkMultiplicity(DefaultChannelPipeline.java:464)
>     at io.netty.channel.DefaultChannelPipeline.addLast0(DefaultChannelPipeline.java:136)
>     at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:129)
>     at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:120)
>     at org.apache.tinkerpop.gremlin.server.channel.HttpChannelizer.configure(HttpChannelizer.java:71)
>     at org.apache.tinkerpop.gremlin.server.AbstractChannelizer.initChannel(AbstractChannelizer.java:134)
>     at org.apache.tinkerpop.gremlin.server.AbstractChannelizer.initChannel(AbstractChannelizer.java:63)
>     at io.netty.channel.ChannelInitializer.channelRegistered(ChannelInitializer.java:69)
>     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRegistered(AbstractChannelHandlerContext.java:133)
>     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRegistered(AbstractChannelHandlerContext.java:119)
>     at io.netty.channel.DefaultChannelPipeline.fireChannelRegistered(DefaultChannelPipeline.java:733)
>     at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:450)
>     at io.netty.channel.AbstractChannel$AbstractUnsafe.access$100(AbstractChannel.java:378)
>     at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:424)
>     at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:357)
>     at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:357)
>     at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:111)
>     at java.lang.Thread.run(Thread.java:745)
> {noformat}
> I fixed this by moving the initialization of the authentication handler in HttpChannelizer from init() to configure(). It doesn't seem like a safe to assumption that the Authenticator interface implementation can be shared.
> 3. After that worked, the other thing I noticed is that if authorization fails, the curl doesn't close.
> {noformat}
> $ curl -k -X POST -v -H 'Content-Type: application/json' -u stephen:bogus https://127.0.0.1:8182 -d '{"gremlin":"100-3"}'
> * Rebuilt URL to: https://127.0.0.1:8182/
> *   Trying 127.0.0.1...
> * Connected to 127.0.0.1 (127.0.0.1) port 8182 (#0)
> * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
> * Server certificate: example.com
> * Server auth using Basic with user 'stephen'
> > POST / HTTP/1.1
> > Host: 127.0.0.1:8182
> > Authorization: Basic c3RlcGhlbjpwYXNz
> > User-Agent: curl/7.43.0
> > Accept: */*
> > Content-Type: application/json
> > Content-Length: 19
> >
> * upload completely sent off: 19 out of 19 bytes
> < HTTP/1.1 401 Unauthorized
> * no chunk, no close, no size. Assume close to signal end
> <
> {noformat}
> I fixed this by adding a listener ChannelFutureListener.CLOSE during the write unautorized response.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)