obiba / agate

OBiBa's user ID provider.
GNU General Public License v3.0
4 stars 7 forks source link

Captcha redirection issue #495

Closed jonathanmassehsj closed 2 years ago

jonathanmassehsj commented 2 years ago

Hi,

Describe the bug Our institution implemented a proxy that filter every request that is made outside of the hospital and it made the recaptcha to doesnt work.

Is it possible to follow the redirection on the recapcha?

Here the screen:

Google chrome error {"code": 500,"message": "Could not extract response: no suitable HttpMessageConverter found for response type [class org.obiba.agate.service.ReCaptchaService$ReCaptchaVerifyResponse] and content type [text/html]","messageTemplate": "error.unhandledException"} image

image

Here is the redirection patern using wget

wget https://www.google.com/recaptcha/api/siteverify --2022-09-27 20:14:05-- https://www.google.com/recaptcha/api/siteverify Resolving www.google.com (www.google.com)... 146.112.250.221, 146.112.47.203, 146.112.47.248, ... Connecting to www.google.com (www.google.com)|146.112.250.221|:443... connected. HTTP request sent, awaiting response... 302 Moved Temporarily Location: https://www.google.com.x.82052ba0091a304b700b81a013fba4f38bb0.9270fa47.id.opendns.com/s/www.google.com/recaptcha/api/siteverify?X-OpenDNS-Session=_82052ba0091a304b700b81a013fba4f38bb09270fa47_4M5Mfzjs_ [following] --2022-09-27 20:14:05-- https://www.google.com.x.82052ba0091a304b700b81a013fba4f38bb0.9270fa47.id.opendns.com/s/www.google.com/recaptcha/api/siteverify?X-OpenDNS-Session=_82052ba0091a304b700b81a013fba4f38bb09270fa47_4M5Mfzjs_ Resolving www.google.com.x.82052ba0091a304b700b81a013fba4f38bb0.9270fa47.id.opendns.com (www.google.com.x.82052ba0091a304b700b81a013fba4f38bb0.9270fa47.id.opendns.com)... 146.112.250.71 Connecting to www.google.com.x.82052ba0091a304b700b81a013fba4f38bb0.9270fa47.id.opendns.com (www.google.com.x.82052ba0091a304b700b81a013fba4f38bb0.9270fa47.id.opendns.com)|146.112.250.71|:443... connected. HTTP request sent, awaiting response... 302 Moved Temporarily Location: https://www.google.com/recaptcha/api/siteverify?X-OpenDNS-Session=_82052ba0091a304b700b81a013fba4f38bb09270fa47_4M5Mfzjs_ [following] --2022-09-27 20:14:05-- https://www.google.com/recaptcha/api/siteverify?X-OpenDNS-Session=_82052ba0091a304b700b81a013fba4f38bb09270fa47_4M5Mfzjs_ Connecting to www.google.com (www.google.com)|146.112.250.221|:443... connected. HTTP request sent, awaiting response... 302 Moved Temporarily Location: /recaptcha/api/siteverify [following] --2022-09-27 20:14:05-- https://www.google.com/recaptcha/api/siteverify Reusing existing connection to www.google.com:443. HTTP request sent, awaiting response... 200 OK Length: unspecified [application/json]

Agate / mica log

Agate / mica doesnt do the redirection and they simple crash instead of going to the redirected link 2022-09-27 20:11:20,194 WARN org.obiba.jersey.exceptionmapper.UnhandledExceptionMapper - Exception catched by UnhandledExceptionMapper org.springframework.web.client.UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [class org.obiba.agate.service.ReCaptchaService$ReCaptchaVerifyResponse] and content type [text/html] at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:126) at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:778) at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:711) at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:437) at org.obiba.agate.service.ReCaptchaService.verify(ReCaptchaService.java:47) at org.obiba.agate.web.rest.user.UsersPublicResource.create(UsersPublicResource.java:193) 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 org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:134) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:177) at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176) at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:81) at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:475) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:397) at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81) at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:255) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:234) at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684) at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:394) at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:311) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1656) at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:292) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) at org.obiba.shiro.web.filter.AuthenticationFilter.doFilterInternal(AuthenticationFilter.java:161) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) at org.obiba.agate.web.filter.NoTraceFilter.doFilter(NoTraceFilter.java:29) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) at org.obiba.agate.web.filter.ClickjackingHttpHeadersFilter.doFilter(ClickjackingHttpHeadersFilter.java:41) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:97) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117) at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:193) at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1626) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:552) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:505) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:772) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) at org.eclipse.jetty.server.Server.handle(Server.java:516) at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:555) at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:410) at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:164) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) at java.lang.Thread.run(Thread.java:750)

To Reproduce You need a proxy server in the network and create redirection.

Many thanks for your help,

ymarcon commented 2 years ago

That is how Google's recaptcha works.

jonathanmassehsj commented 2 years ago

Thank you for your quick reply @ymarcon,

Would you like to disable the recaptcha? The best would be to keep it to avoid bot creating fake account and mostly because we have a few important projects.

Would it work if Agate authenticates with the proxy? No, in our institution, we really need to pass the request using the OpenDNS server that is creating a few 302 redirection and cause the request to fail in agate.

I think you will see more and more people with the same issue specially if they have in a very strict network. (OpenDNS is becoming more popular)

I'm not sure if this help but I found this : https://www.wranto.com/2018/03/Spring-RestTemplate-AutoRedirect.html

The code that doesnt do the HTTP 302 redirection seems to be at this place image

Many thanks for your help @ymarcon, hopefully the next agate version will do or allow the redirection for the google captcha so people using OpenDNS will be able to use it.

ymarcon commented 2 years ago

Thanks for the hint. Do you an environment where you could test a snapshot version of agate?

jonathanmassehsj commented 2 years ago

@ymarcon yes, I have a test environment (inside the same network) that has the same issue and I will be able to test the snapshot version on it.

ymarcon commented 2 years ago

Ok then I'll let you know. What type of package do you use? docker image, debian, rpm, zip?

jonathanmassehsj commented 2 years ago

Ubuntu 22.04 x64 (.deb)

ymarcon commented 2 years ago

Please have a try with 2.7.4-beta.

jonathanmassehsj commented 2 years ago

@ymarcon many thanks for your quick reply, you're the best,

Seems to work in part.

Now the captcha seems to work.

If I didn't do the captcha (selecting the wrong item and element) I receive : {"code": 400,"message": "Invalid reCaptcha response","messageTemplate": "server.error.bad-request"} Which is good

But I'm not sure why but If the captcha is valid, I receive {code: 400, message: "Missing attribute nonDisclosure", messageTemplate: "server.error.bad-request"} (So captcha now work well and is validated)

image

image

(On our project we have a checkbox before creating the user for the non disclosure)

The non disclosure field is checked and there in the request

The weird part is if I remove the username, I have {"code": 400,"message": "User name cannot be empty","messageTemplate": "server.error.bad-request"}

So all fields seems to work perfectly but not the one called nonDisclosure. (The field nonDisclosure itself is sent via POST like the others fields)

I checked the logs file and no more captcha error only this one is happening 2022-09-28 13:43:58,776 ERROR org.obiba.mica.user.UserProfileService - Client error on user creation: {"code": 400,"message": "Missing attribute nonDisclosure","messageTemplate": "server.error.bad-request"}

jonathanmassehsj commented 2 years ago

Here is the sign up page with the non disclosure field

image

jonathanmassehsj commented 2 years ago

@ymarcon I will try to disable captcha and use the old version, if there a way to disable the captcha for sign up?

ymarcon commented 2 years ago

This is a different issue. I know what it is (some incompatibility between new jetty and jersey versions), I'll fix it.

ymarcon commented 2 years ago

Please try again with 2.7.4-beta2.

jonathanmassehsj commented 2 years ago

Everything works :tada:

You're the best @ymarcon

ymarcon commented 2 years ago

2.7.4 has been released, thanks for the feedback, it is was very helpful.