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

Header Authentification #724

Closed
tchiotludo opened this issue Jun 2, 2021 · 26 comments
Closed

Header Authentification #724

tchiotludo opened this issue Jun 2, 2021 · 26 comments
Labels
enhancement New feature or request login Login & Acls on AKHQ

Comments

@tchiotludo
Copy link
Owner

Allow to use Header coming reverse proxy to auth user.
maybe like that :

akhq:
  security: 
    header:
      user-header: X-Akhq-User 
      group-header: X-Akhq-Group 
      users: 
        username: 
          groups:
            - admin
@tchiotludo tchiotludo added enhancement New feature or request login Login & Acls on AKHQ labels Jun 2, 2021
@skaravad
Copy link

skaravad commented Jun 2, 2021

This is exactly what I was looking for, but we might not have to explicitly set the username and the groups to which the user belongs to under the users, once the user belongs to the group (which is already implied when the we make the auth request, the incoming header has both username and group ) , so based on the group-header we can define the roles/privileges.

@skaravad
Copy link

Hi @tchiotludo , hope you are doing well, any ETA when this can be implemented ?

Thank you.

@tchiotludo
Copy link
Owner Author

hi @skaravad, It's done on the dev version (in 15 minutes).
Can you try please to see if it's meet your requirements ?

@piotrp
Copy link
Contributor

piotrp commented Aug 12, 2021

Shouldn't this be (optionally?) secured by an IP whitelist, so that people won't be able to go around auth proxy even when application listens on public port?

@tchiotludo
Copy link
Owner Author

This can be done easily I think @piotrp, a PR will be welcome 👍

@piotrp
Copy link
Contributor

piotrp commented Aug 12, 2021

I think I have some time, will check. Should I create issue for this or just submit PR?

@tchiotludo
Copy link
Owner Author

maybe create the issue for the memory 👍
and to help micronaut have a matching ip filter that you can use as inspiration

@skaravad
Copy link

skaravad commented Aug 12, 2021

@piotrp @tchiotludo thank you for the feature, really appreciate it. I'm about to try the dev build , just need some help with the config, as per the documentation

# Header configuration (reverse proxy)
    header-auth:
      user-header: x-akhq-user # mandatory (the header name that will contain username)
      groups-header: x-akhq-group # optional (the header name that will contains groups separated by coma `,`)
      users: # mandatory, the users list allow
        - username: header-user # username matching the `user-header` value
          groups: # list of group for current users
            - topic-reader
        - username: header-admin
          groups:
            - admin

Do we need to specify the users who are allowed to login ? in the sense lets say we have 4 admin users and 20 developers , so we need to pre-populate them under users like

      users: # mandatory, the users list allow
        - username: user1
          groups: 
            - topic-reader
        - username: user2
          groups: 
            - topic-reader
        - username: admin1
          groups:
            - admin
        - username: admin2
          groups:
            - admin

Not sure if this is the case, but if so, then then authentication is not dynamic via header, from my understanding if a user-header is being sent to akhq, then the user is already trusted (even in the case of IP address, it is the responsibility of the admin to control access to the proxy at proxy level vs akhq to check for the IP), when it comes to authorization, like admin or reader the group should be the one controlling it.

@tchiotludo tchiotludo reopened this Aug 12, 2021
@tchiotludo
Copy link
Owner Author

I could make an optional users props, in this case, you must have groups-header properties.
Does it make sense for you ?

@skaravad
Copy link

Yes, that makes it more dynamic, just like other dynamic auth mechanism like LDAP , all we need to know is which group the user belongs to and then apply the group permissions.

@tchiotludo
Copy link
Owner Author

@skaravad it's done, can you try please ?

@skaravad
Copy link

@tchiotludo thank you, will test it in a bit.

@skaravad
Copy link

skaravad commented Aug 13, 2021

@tchiotludo @piotrp , it is working as expected, thank you so much. On a side note, I don't think the error log below is related to this change, but here is something I see

2021-08-13 00:12:59,149 ERROR Group-1-10 o.a.c.ErrorController      Connection reset by peer
java.io.IOException: Connection reset by peer
	at java.base/sun.nio.ch.FileDispatcherImpl.read0(Native Method)
	at java.base/sun.nio.ch.SocketDispatcher.read(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
	at java.base/sun.nio.ch.SocketChannelImpl.read(Unknown Source)
	at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253)
	at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132)
	at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
	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(Unknown Source)
2021-08-13 00:12:59,150 ERROR pGroup-1-3 o.a.c.ErrorController      Connection reset by peer
java.io.IOException: Connection reset by peer
	at java.base/sun.nio.ch.FileDispatcherImpl.read0(Native Method)
	at java.base/sun.nio.ch.SocketDispatcher.read(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
	at java.base/sun.nio.ch.IOUtil.read(Unknown Source)
	at java.base/sun.nio.ch.SocketChannelImpl.read(Unknown Source)
	at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:253)
	at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132)
	at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:350)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
	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(Unknown Source

if this is not related to the auth changes, then this issue can be marked as closed, will wait for the official release.
Thank you again.

@skaravad
Copy link

One minor issue, though I does not bother me much, on logout we get redirected to /akhq/ui/login and to login again we need to hit the base url in our case /akhq to login again , a login button post logout would make it perfect, not a show stopper at all.
Thank you again for your quick turnaround and amazing work.

@tchiotludo
Copy link
Owner Author

maybe a better option is to disable completely logout button with auth header, it doesn't make sense no ?

@skaravad
Copy link

skaravad commented Aug 13, 2021

That works too, or on logout redirect them to base-path (I handled it at the haproxy level with this re-direct condition to mimic other apps like grafana / jenkins which support header auth)

What you suggested makes perfect sense with no logout button. Here is what I did on haproxy side.

backend akhq
    http-request redirect location /akhq if { path /akhq/ui/login }
    server akhq akhq:8081

@piotrp
Copy link
Contributor

piotrp commented Aug 15, 2021

@tchiotludo current version fails when it's run using configuration that doesn't define header authentication data. I get an exception:

14:36:20.753 [default-nioEventLoopGroup-1-2] INFO  o.a.m.HeaderAuthenticationFetcher - HeaderAuth(userHeader=null, groupsHeader=null, users=null)
14:36:20.763 [default-nioEventLoopGroup-1-2] ERROR org.akhq.controllers.ErrorController - name
java.lang.NullPointerException: name
        at io.netty.util.internal.ObjectUtil.checkNotNull(ObjectUtil.java:39)
        at io.netty.handler.codec.DefaultHeaders.getAll(DefaultHeaders.java:161)
        at io.netty.handler.codec.HeadersUtils.getAllAsString(HeadersUtils.java:42)
        at io.netty.handler.codec.http.DefaultHttpHeaders.getAll(DefaultHttpHeaders.java:264)
        at io.micronaut.http.netty.NettyHttpHeaders.get(NettyHttpHeaders.java:95)
        at io.micronaut.core.value.ValueResolver.get(ValueResolver.java:53)
        at org.akhq.modules.HeaderAuthenticationFetcher.fetchAuthentication(HeaderAuthenticationFetcher.java:46)
        at io.micronaut.security.filters.SecurityFilter.lambda$doFilterOnce$0(SecurityFilter.java:110)
        at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onNext(FlowableFlatMap.java:132)
        at io.micronaut.reactive.rxjava2.RxInstrumentedSubscriber.onNext(RxInstrumentedSubscriber.java:59)
        at io.reactivex.internal.operators.flowable.FlowableFromIterable$IteratorSubscription.slowPath(FlowableFromIterable.java:236)
        at io.reactivex.internal.operators.flowable.FlowableFromIterable$BaseRangeSubscription.request(FlowableFromIterable.java:124)
        at io.reactivex.internal.operators.flowable.FlowableFlatMap$MergeSubscriber.onSubscribe(FlowableFlatMap.java:117)
        at io.micronaut.reactive.rxjava2.RxInstrumentedSubscriber.onSubscribe(RxInstrumentedSubscriber.java:52)
        at io.reactivex.internal.operators.flowable.FlowableFromIterable.subscribe(FlowableFromIterable.java:69)
        at io.reactivex.internal.operators.flowable.FlowableFromIterable.subscribeActual(FlowableFromIterable.java:47)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.Flowable.subscribe(Flowable.java:14865)
        at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:57)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.internal.operators.flowable.FlowableFlatMap.subscribeActual(FlowableFlatMap.java:53)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.internal.operators.flowable.FlowableElementAtMaybe.subscribeActual(FlowableElementAtMaybe.java:36)
        at io.reactivex.Maybe.subscribe(Maybe.java:4290)
        at io.micronaut.reactive.rxjava2.RxInstrumentedMaybe.subscribeActual(RxInstrumentedMaybe.java:53)
        at io.reactivex.Maybe.subscribe(Maybe.java:4290)
        at io.reactivex.internal.operators.maybe.MaybeDoOnEvent.subscribeActual(MaybeDoOnEvent.java:39)
        at io.reactivex.Maybe.subscribe(Maybe.java:4290)
        at io.reactivex.internal.operators.maybe.MaybeToFlowable.subscribeActual(MaybeToFlowable.java:45)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.internal.operators.flowable.FlowableFlatMap.subscribeActual(FlowableFlatMap.java:53)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty.subscribeActual(FlowableSwitchIfEmpty.java:32)
        at io.reactivex.Flowable.subscribe(Flowable.java:14918)
        at io.reactivex.Flowable.subscribe(Flowable.java:14868)
        at io.micronaut.configuration.metrics.binder.web.WebMetricsPublisher.subscribe(WebMetricsPublisher.java:155)
        at io.micronaut.http.server.netty.RoutingInBoundHandler.executeRoute(RoutingInBoundHandler.java:1119)
        at io.micronaut.http.server.netty.RoutingInBoundHandler.handleRouteMatch(RoutingInBoundHandler.java:775)
        at io.micronaut.http.server.netty.RoutingInBoundHandler.channelRead0(RoutingInBoundHandler.java:606)
        at io.micronaut.http.server.netty.RoutingInBoundHandler.channelRead0(RoutingInBoundHandler.java:148)
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:102)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.micronaut.http.netty.stream.HttpStreamsHandler.channelRead(HttpStreamsHandler.java:199)
        at io.micronaut.http.netty.stream.HttpStreamsServerHandler.channelRead(HttpStreamsServerHandler.java:123)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
        at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
        at io.netty.handler.codec.http.HttpServerKeepAliveHandler.channelRead(HttpServerKeepAliveHandler.java:64)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.handler.flow.FlowControlHandler.dequeue(FlowControlHandler.java:200)
        at io.netty.handler.flow.FlowControlHandler.channelRead(FlowControlHandler.java:162)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
        at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
        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:829)

First line is from additional logging I added to HeaderAuthenticationFetcher. Looks like Header Auth is running despite it being not configured, and fails at request.getHeaders().get(null, String.class).

What's the desired behavior? Should there be a null check there (I can add it in PR I'm preparing) or should HeaderAuthenticationFetcher not run at all when not configured?

@tchiotludo tchiotludo reopened this Aug 15, 2021
@piotrp
Copy link
Contributor

piotrp commented Aug 15, 2021

While we're still on topic: would it be ok to add group mappings, so that header auth would get feature parity with LDAP and OIDC providers?

tchiotludo pushed a commit that referenced this issue Aug 16, 2021
#792)

* allow to run without header authentication
* customizable group separator for header authentication

relate to #724
tchiotludo added a commit that referenced this issue Aug 16, 2021
@tchiotludo
Copy link
Owner Author

@skaravad : If disabled login button if only header auth

@piotrp : this is already enable here, or I don't understand your question ?

tchiotludo added a commit that referenced this issue Aug 16, 2021
@piotrp
Copy link
Contributor

piotrp commented Aug 16, 2021

I meant this group mapping, eg. for LDAP you can use:

akhq:
  security:
    ldap:
      groups:
        - name: mathematicians
          groups:
            - topic-reader
        - name: scientists
          groups:
            - topic-reader
            - topic-writer

And it would make sense if header authentication could also perform similar mapping.

@tchiotludo
Copy link
Owner Author

ok got it map custom group from headers with local ahhq group, make sense
Do you want to make a PR for that ?

@piotrp
Copy link
Contributor

piotrp commented Aug 16, 2021

PR: #794

tchiotludo pushed a commit that referenced this issue Aug 17, 2021
@skaravad
Copy link

@tchiotludo @piotrp in the latest dev the header auth is broken, not sure what could be the reason, the user-header is not being picked up and the user defaults to Anonymous

2021-09-15 21:56:20,041 INFO  pGroup-1-5 org.akhq.log.access        [Date: 2021-09-15T21:56:20.040671Z] [Duration: 0 ms] [Url: GET /akhq/ui/static/media/icon.648ce9c8.svg] [Status: 200] [Ip: /192.168.1.5] [User: Anonymous]
2021-09-15 21:56:20,078 INFO  pGroup-1-6 org.akhq.log.access        [Date: 2021-09-15T21:56:20.077898Z] [Duration: 0 ms] [Url: GET /akhq/ui/static/media/logo.45903e1f.svg] [Status: 200] [Ip: /192.168.1.5] [User: Anonymous]
2021-09-15 21:56:20,156 INFO  pGroup-1-8 org.akhq.log.access        [Date: 2021-09-15T21:56:20.156117Z] [Duration: 0 ms] [Url: GET /akhq/ui/static/media/fontawesome-webfont.af7ae505.woff2] [Status: 200] [Ip: /192.168.1.5] [User: Anonymous]
2021-09-15 21:56:20,930 INFO  r-thread-2 org.akhq.log.access        [Date: 2021-09-15T21:56:20.063127Z] [Duration: 866 ms] [Url: GET /akhq/api/kafka/topic] [Status: 200] [Ip: /192.168.1.5] [User: Anonymous]
2021-09-15 21:56:21,034 ERROR pGroup-1-7 o.a.c.ErrorController      Connection reset by peer

@piotrp
Copy link
Contributor

piotrp commented Sep 16, 2021

I have a working configuration with current dev branch (from 9th September, so without last commit). Can you enable debug logging for org.akhq.modules.HeaderAuthenticationFetcher? For each request you should see a line saying "One or more of the IP patterns matched the host address [...]. Continuing request processing.". If not, then header is not present or AKHQ will log a reason for why it won't continue header processing.

Have you tried issuing manual HTTP request with user-header header?

@tchiotludo
Copy link
Owner Author

thanks @piotrp for the good response.
I've also a working version deployed on kubernetes cluster so @skaravad please provide some log 👍

@skaravad
Copy link

hi @piotrp @tchiotludo , thank you for quick response, it appears that I had a cached copy of dev image, it is working now, however post login , in the UI there is no user info (in the top right corner), not sure if this is expected.

here is the log

2021-09-16 15:47:59,170 DEBUG pGroup-1-3 eaderAuthenticationFetcher One or more of the IP patterns matched the host address [192.168.1.5]. Continuing request processing.
2021-09-16 15:47:59,203 INFO  pGroup-1-3 org.akhq.log.access        [Date: 2021-09-16T15:47:59.19503Z] [Duration: 9 ms] [Url: GET /akhq/ui] [Status: 200] [Ip: /192.168.1.5] [User: skaravad@xxxxxxx.com]

On a side note, if the log can also print the group header , that can be really useful for debugging.

tchiotludo pushed a commit that referenced this issue Oct 24, 2021
#792)

* allow to run without header authentication
* customizable group separator for header authentication

relate to #724
tchiotludo added a commit that referenced this issue Oct 24, 2021
@tchiotludo tchiotludo reopened this Oct 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request login Login & Acls on AKHQ
Projects
Status: Done
Development

No branches or pull requests

3 participants