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

Problems running behind https #1485

Closed
marthjod opened this issue May 6, 2021 · 12 comments
Closed

Problems running behind https #1485

marthjod opened this issue May 6, 2021 · 12 comments
Labels
type/question Further information is requested

Comments

@marthjod
Copy link

marthjod commented May 6, 2021

We are running the the Registry as a Kubernetes deployment (quay.io/apicurio/apicurio-registry-sql:2.0.0.Final) and accessing it behind an HTTPS reverse proxy. We had to override

  • REGISTRY_UI_CONFIG_APIURL=https://...
  • REGISTRY_UI_CONFIG_UIURL=https://...

with https:// URLs to avoid Mixed Content errors where the browser complains about plain HTTP XHR requests for the HTTPS page (somewhat related: #1152; #513; see also https://www.apicur.io/registry/docs/apicurio-registry/2.0.0.Final/getting-started/assembly-managing-registry-artifacts-ui.html).

Accessing /ui now throws this error complaining about an http:// URL:

javax.ws.rs.NotFoundException: RESTEASY003210: Could not find resource for full path: http://apicurio-registry.internal.example.io/apis/v2/search/artifacts?limit=10&order=asc&orderby=name
	at org.jboss.resteasy.core.registry.ClassNode.match(ClassNode.java:70)
	at org.jboss.resteasy.core.registry.RootClassNode.match(RootClassNode.java:47)
	at org.jboss.resteasy.core.ResourceMethodRegistry.getResourceInvoker(ResourceMethodRegistry.java:481)
	at org.jboss.resteasy.core.SynchronousDispatcher.getInvoker(SynchronousDispatcher.java:332)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:253)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
	at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
	at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
	at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:249)
	at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.service(ResteasyFilter.java:70)
	at io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.sendError(ResteasyFilter.java:76)
	at io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:172)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:503)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
	at io.quarkus.resteasy.runtime.ResteasyFilter.doFilter(ResteasyFilter.java:31)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.apicurio.registry.ui.servlets.ResourceCacheControlFilter.doFilter(ResourceCacheControlFilter.java:83)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.apicurio.registry.rest.RegistryApplicationServletFilter.doFilter(RegistryApplicationServletFilter.java:113)
	at io.apicurio.registry.rest.RegistryApplicationServletFilter_ClientProxy.doFilter(RegistryApplicationServletFilter_ClientProxy.zig:225)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63)
	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:67)
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133)
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65)
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:247)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:56)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:111)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:108)
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1.call(UndertowDeploymentRecorder.java:574)
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:152)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$1.handleRequest(UndertowDeploymentRecorder.java:117)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:290)
	at io.undertow.server.DefaultExchangeHandler.handle(DefaultExchangeHandler.java:18)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$5$1.run(UndertowDeploymentRecorder.java:400)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2415)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
	at java.base/java.lang.Thread.run(Thread.java:834)
	at org.jboss.threads.JBossThread.run(JBossThread.java:501)

Is this a known issue? How do we make the Registry properly work behind https? Is this even an HTTPS-related or rather a URL path problem?
https://apicurio-registry.internal.example.io/apis/ works fine.

@EricWittmann
Copy link
Member

EricWittmann commented May 6, 2021

There should be some console logging in the browser - if you could provide that it would help. But if you're getting a stack trace from the server, the implication certainly is that the request is reaching the server but then failing. The error you are seeing is what you would get if you tried accessing an endpoint that doesn't exist. For example:

https://apicurio-registry.internal.example.io/apis/v2/search/galaxies

Since there is no /search/galaxies endpoint you'll see this error (verified locally):

Could not find resource for full path: http://localhost:8080/apis/registry/v2/search/galaxies

What happens if you do this?

curl https://apicurio-registry.internal.example.io/apis/registry/v2/system/info

When I do that, I get this output:

$ curl http://localhost:8080/apis/registry/v2/system/info
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   181  100   181    0     0   5027      0 --:--:-- --:--:-- --:--:--  5027
{"name":"Apicurio Registry (In Memory)","description":"High performance, runtime registry for schemas and API designs.","version":"2.0.0.Final","builtOn":"2021-04-16T15:03:49+0000"}

@EricWittmann EricWittmann added the type/question Further information is requested label May 6, 2021
@marthjod
Copy link
Author

marthjod commented May 7, 2021

Thanks for your swift reply.
The browser console essentially shows the 404 that's caused by the above error.

[ConfigService] Found app config.
logger.service.js:45 Using app contextPath:  /ui
logger.service.js:45 [BaseService] Using REST endpoint:  https://apicurio-registry.internal.example.io/apis/v2/search/artifacts?limit=10&order=asc&orderby=name
logger.service.js:45 [BaseService] Making a GET request to:  https://apicurio-registry.internal.example.io/apis/v2/search/artifacts?limit=10&order=asc&orderby=name
/apis/v2/search/artifacts?limit=10&order=asc&orderby=name:1 Failed to load resource: the server responded with a status of 404 ()

Here's the response from your proposed curl command:

{"name":"Apicurio Registry (SQL)","description":"High performance, runtime registry for schemas and API designs.","version":"2.0.0.Final","builtOn":"2021-04-16T15:03:49+0000"}

If I understand you correctly, URLs are transformed into a http/localhost version internally? https://apicurio-registry.internal.example.io/apis/v2/search/galaxies causes a lookup for http://localhost:8080/apis/registry/v2/search/galaxies? Then setting REGISTRY_UI_CONFIG_APIURL (which we need for other reasons) might be causing this transformation to fail.

Is there a recommended way to host the Registry behind an HTTPS-enabled reverse proxy? Is this supported?

@EricWittmann
Copy link
Member

Yes running behind a https enabled reverse proxy should be no problem at all! That's pretty much how we always run the registry when deployed in e.g. OpenShift or Kubernetes. SSL is enabled at the edge, not in the application. So we're always deploying the way you describe. This is very strange.

If that previous curl command I sent worked, then the rest of the API should work too. What happens if you try to curl the exact URL that is failing in the UI?

curl https://apicurio-registry.internal.example.io/apis/v2/search/artifacts?limit=10&order=asc&orderby=name

Does that also fail?

@Apicurio/developers Any ideas?

@marthjod
Copy link
Author

Yes, that fails with the same 404 and error message mentioning http:// I pasted above.

@marthjod
Copy link
Author

marthjod commented May 11, 2021

We're behind Cloudflare Access, if that gives you any hint? Still looks like something Registry UI-internal is getting mixed up to me, though.

@marthjod
Copy link
Author

@EricWittmann
Copy link
Member

Oh man there is a subtle difference in those URLs that I didn't notice until you laid it out like that. :) OK, so can you provide your exact values for REGISTRY_UI_CONFIG_APIURL and REGISTRY_UI_CONFIG_UIURL?

@EricWittmann
Copy link
Member

I think maybe the value of REGISTRY_UI_CONFIG_APIURL you're setting is just missing the last /registry path section.

@marthjod
Copy link
Author

They were
REGISTRY_UI_CONFIG_APIURL: https://apicurio-registry.internal.example.io/apis
REGISTRY_UI_CONFIG_UIURL: https://apicurio-registry.internal.example.io/ui,
now they are
REGISTRY_UI_CONFIG_APIURL: https://apicurio-registry.internal.example.io/apis/registry
REGISTRY_UI_CONFIG_UIURL: https://apicurio-registry.internal.example.io/ui
and the UI works properly!
Thank you so much 🥇
I was following the example here https://www.apicur.io/registry/docs/apicurio-registry/2.0.0.Final/getting-started/assembly-managing-registry-artifacts-ui.html, which has /apis. Should that maybe be updated or mention the registry part?

@upvest-juha
Copy link

Yay, it works. Thank you.

@jsenko
Copy link
Member

jsenko commented May 13, 2021

@smccarthy-ie hi, Could you please add this to the documentation updates?

@smccarthy-ie
Copy link
Contributor

Hi @jsenko This is waiting to be merged in #1488 :)

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

No branches or pull requests

5 participants