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

Authservice not accepting http endpoints: invalid authorization_uri #86

Closed
MeghanaSrinath opened this issue Mar 24, 2020 · 7 comments
Closed

Comments

@MeghanaSrinath
Copy link

We are trying to set up the authentication with Istio and keycloak by following the guide here.

We have installed keycloak on our k8s cluster and have exposed it on port 80 as http load balancer.
Keycloak endpoints are http and the 'Require SSL' is set to 'none' at the realm level.
We have configured these endpoints in config/authservice-configmap-template-for-authn.yaml. Istio sidecar injection in enabled in the cluster.

However on applying config/bookinfo-with-authservice-template.yaml, the productpage pod is going to CrashLoopBackOff state with the below error log in the authservice container:

[2020-03-24 08:25:11.162] [console] [error] main: Unexpected error: invalid authorization_uri: uri must be https scheme: http://<ip>/auth/realms/<realm>/protocol/openid-connect/auth

Doesn't authservice support keycloak http endpoints?
In case https endpoints are mandatory for authservice, is there a restriction on how the certificates are generated for keycloak or istio? Should it be a trusted root certificate or can it be a self-signed certificate?

Istio version: 1.4.5
Kubectl version: v1.14.10-gke.17

@cfryanr
Copy link

cfryanr commented Mar 24, 2020

Hi @MeghanaSrinath, thanks for reaching out and sharing the details of your issue.

So far we've written the code to only support https, because we thought that in practice everyone would want to use https for security reasons, even in non-production systems. We're certainly open to feedback on that and would appreciate any details you could provide on your use case and why you've set up your system to use http.

In terms of certificates, there is no particular restriction. The Authservice will check the full validity of the server's certificate, including checking that the container's OS trusts the CA. We recently introduced a setting called trusted_certificate_authority in the config (see docs at docs/README.md) to allow you to configure any CA to be additionally trusted, which makes it easy to trust systems who certs perhaps were not signed by a generally trusted CA.

@MeghanaSrinath
Copy link
Author

Hi @cfryanr ,
Thanks for the clarifications. We have actually setup keycloak to be accessed via nginx ingress. A DNS record is created for this nginx ingress and certmanager is used to authenticate the ownership of the DNS (Thanks to @snkshukla 's help on this). So authservice works perfectly with this setup.
But when we use keycloak as a load balancer by exposing it on port 443 (with no certmanager), we weren't able to redirect back to the application page after keycloak login. We could see the below errors in keycloak container:

03:19:39,280 ERROR [io.undertow.request] (default I/O-2) Closing SSLConduit after exception on handshake: javax.net.ssl.SSLHandshakeException: Client requested protocol SSLv3 is not enabled or supported in server context
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:254)
        at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.negotiateProtocol(ClientHello.java:883)
        at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:835)
        at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1048)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:995)
        at io.undertow.core@2.0.27.Final//io.undertow.protocols.ssl.SslConduit$5.run(SslConduit.java:1072)
        at org.jboss.threads@2.3.3.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
        at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
        at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
        at java.base/java.lang.Thread.run(Thread.java:834)

03:20:02,929 ERROR [io.undertow.request] (default I/O-2) Closing SSLConduit after exception on handshake: javax.net.ssl.SSLHandshakeException: no cipher suites in common
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:263)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:254)
        at java.base/sun.security.ssl.ServerHello$T12ServerHelloProducer.chooseCipherSuite(ServerHello.java:460)
        at java.base/sun.security.ssl.ServerHello$T12ServerHelloProducer.produce(ServerHello.java:295)
        at java.base/sun.security.ssl.SSLHandshake.produce(SSLHandshake.java:436)
        at java.base/sun.security.ssl.ClientHello$T12ClientHelloConsumer.consume(ClientHello.java:1102)
        at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.onClientHello(ClientHello.java:854)
        at java.base/sun.security.ssl.ClientHello$ClientHelloConsumer.consume(ClientHello.java:813)
        at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:392)
        at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:443)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1061)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(SSLEngineImpl.java:1048)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(SSLEngineImpl.java:995)
        at io.undertow.core@2.0.27.Final//io.undertow.protocols.ssl.SslConduit$5.run(SslConduit.java:1072)
        at org.jboss.threads@2.3.3.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
        at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
        at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
        at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
        at java.base/java.lang.Thread.run(Thread.java:834)

This made us wonder if not having certificates at keycloak level is causing this issue, as everything worked fine with the first setup.
If you can provide us with any clarifications regarding this, that'd be great!

Now from the implementation perspective, we have a use case wherein we are automating this entire authentication setup with keycloak, istio and authservice. So, considering the first setup with nginx ingress, we wont be able to create any DNS record beforehand and it has to be done on the fly. We are still exploring other options on this.
Hence, we were wondering if authservice can work with http so all of this can be simplified.
Please let me know your thoughts on this :)

@cfryanr
Copy link

cfryanr commented Mar 26, 2020

@MeghanaSrinath, thanks for explaining your use case more. There's one more thing that I don't think I'm understanding...

It sounds like you're at the step where keycloak has redirected the user's browser back to the application, the authservice has intercepted that request and is trying to make an HTTPS POST request back to keycloak to exhange the authcode for some tokens. From your keycloak logs, I'm guessing that keycloak was not configured to accept HTTPS requests?

That particular request has the oauth client ID and client secret in plain text as a header, has the authorization code in plain text as a param, and has the user's tokens in plain text in the response body. As you know, all of those secrets would be potentially devastating to the security posture of your app if they were leaked to an outside observer. That observer would, at the very least, be able to act as the user who was trying to log in to the app, and not just for now, but also be able act as that user for the indefinite future until the user's refresh token expired. This is why we were assuming that you would want to protect that data in transit by using TLS encryption in all cases, even in non-prod systems.

I'm curious if maybe you have some other data protection scheme in mind, and maybe that's why you're suggesting that HTTP would be okay for your use case?

@MeghanaSrinath
Copy link
Author

@cfryanr , We were looking at options whether we can secure this while having HTTP, but we haven't yet come to any conclusion. So we do not have much on this idea yet. But yes, HTTPS is always a better way to do it.

It sounds like you're at the step where keycloak has redirected the user's browser back to the application, the authservice has intercepted that request and is trying to make an HTTPS POST request back to keycloak to exhange the authcode for some tokens. From your keycloak logs, I'm guessing that keycloak was not configured to accept HTTPS requests?

Yes, you are right. Its at this step, we're having the issue.
We have exposed keycloak on port 443 as HTTPS LoadBalancer. But still we obtained the errors which I have posted in my previous thread. Authservice worked totally fine when keycloak was accessed via nginx ingress with the required certificates.
So we were just wondering if there is any additional setup that is required for keycloak or authservice with respect to the ingress/certificates part.
Please let me know your thoughts on this!

@cfryanr
Copy link

cfryanr commented Apr 2, 2020

Hi @MeghanaSrinath, I'm sorry, I'm not sure what's happening with your keycloak setup. The Java exception log messages that you shared previously makes it look as though the key manager for accepting incoming TLS connections is not configured correctly, however I'm not personally familiar with using Keycloak, so I'm not sure. My guess is that there could be more configuration that you would need to do for Keycloak. Perhaps reviewing this part of their guide might help: https://www.keycloak.org/docs/latest/server_installation/#_setting_up_ssl

@MeghanaSrinath
Copy link
Author

@cfryanr , Thank you for the analysis. I will check my keycloak configuration.

@zimmertr
Copy link

HTTP is useful for local dev. I have a small Kustomize project to deploy Istio, Authservice, and Keycloak to Minikube and the requirement for Keycloak to leverage TLS adds a lot of complexity to something that would otherwise normally be simple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants