-
Notifications
You must be signed in to change notification settings - Fork 44
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
external-auth-server with keycloak and ambassador #16
Comments
This is great! I've been hoping for some help with Ambassador. There's a lot to digest here so let me break it down as much as possible:
Let's (for the time being) remove the Looking forward to getting it going for you and getting ambassador documented! |
When i look at ambassador i see:
|
|
Did a bit more reading up on the ambassador documentation... I found that you can add a path_prefix to the arguments, so i tried this:
And that seems to append the config to the routing correctly :) |
So..... Status update..... After updating the config with the path_prefix, i got a lot further in the process.
|
Or better formatted:
|
In case you want some debug info..... these are the configuration of that last call that fails:
|
hmmm ..... that seemed to be a fuck-up on my side..... i accidentally had added some of the parameters twice in my request for the oauth callback..... |
Now the authentication looks like this:
I wonder what the undefinedundefined url is should have been |
Wow great progress! This is all awesome info. That's likely related to the original uri detection. One thing that would be helpful now is to the the log level to That will help detect what headers are being passed and how they're formatted. Send that over and I'll read the doc you send previously and we'll get that last piece knocked out...I think you're very close, thanks for the willingness to help out! |
I've read the doc and noticed that I'll also need to make the auth service support all the http verbs as ambassador doesn't always make a So yeah, at this point just send me the output after enabling |
This must be the debug message you were looking for:
|
Nope, it's before that even..you must have the log level set to |
A bit more log info:
|
If you are wondering about the user-agent...... im using python to intercept all the calls and redirect so that i can see the headers, content, parameters and cookie on every step along the way |
Ok, that 3rd entry is what I'm after. Can you send that on a fresh request to your end user service? When you send it also send the actual url you requested like: |
Adding that in as an additional proxy may be harmful to uri detection but we'll see... |
I think i have found the issue......
As you can see, in info block 5 |
In other words.... the missing link is in src/util. js line 80 the header x-forwarded-host is missing or empty |
Yes, exactly. That's what extra logic I need to code to work better with ambassador (should be very simple once I have a better idea of the passed headers). Notice the first block, is there any way you can configure ambassador to send down the path info there? ie: In the end, I just need enough info in the headers to completely reconstruct the full originally requested URI. |
Actually location is for the response (duh) sorry. Anyhow, if you know of a way to configure ambassador to send down the full request details in some shape or form we can get you going quickly.. |
It probably would be helpful to remove the python proxy at this point and observe output without that additional layer too.. |
I've read the ambassador doc more thoroughly and it looks like the approach is even more different than I originally thought. You mentioned earlier you can inject the token as a header, have you tried that with another service and does it work (header injection)? I think I know how ambassador can be tooled to work nicely but we'll need that for sure from what I can tell.. |
Yep, header injection is possible and quite simple, as long as the value is static.... i dont know if we can do dynamic headers if that is what you are thinking :) |
I seem to be missing something somewhere..... i end up in a endless loop, with request to page => redirect to authservice => redirect to keycloak => redirect to authservice => redirect back to the initial web-page which redirects to authservice (authentication fails ) => redirects to keycloak |
Ouch. Can you send me all the Were you able to get any more details on what headers can be (or are) being passed down by bypassing the python proxy? I noticed in one of the first examples you sent it had this header I'm going to do some preliminary work on better supporting ambassador and get into my Regarding the header, yes static. Ambassador takes a very different approach to this than traefik does...contrary to my original perception. I uses a sort of overlay idea whereas traefik just requests an (static) external arbitrary URL. What I intend to do is the following:
At that point the only missing piece will be proper URI reconstruction (only really required for |
I just sat up traefik to see if i can get it working with that.... ill circle back to this one, once i have verified that all of the other components are working exactly as they should..... ill give a update once im further in the process :) ..... but thank you so much for your help so far |
OK, I've already coded everything to support ambassador too minus the host stuff. I don't even need the path portion as that can be derrived based on the ambassador spec and how it works. But I still need the original scheme/host/port somehow... |
Worst case scenario if ambassador can't send that info down as a header(s) then I can introduce a simple configuration param that's specific to ambassador to be passed in as a static value via header injection...pretty simple stuff. I am headed out shortly for the weekend so likely won't be very responsive until Monday (in North America) comes around. |
Hey... no worries.... im going off for weekend in -2 hours as well ;) |
Right now im just testing and yes i have two plugins in one config.... however, before i move this to production, im going to split it into one config for the front end and one for api's.... |
You can use a single config and use the I'll just clean up the jwks code and commit it to I've never used tokens from keycloak like that (only the authorization code flow so far), if you've got a link you used send it over so I can see the general idea. If you're interested in Going back to the very beginning when you're ready to revisit server-side tokens let me know as well. |
Awesome!... ill use the pcb functionality and keep a close eye on next brance 👍 ...
Im currently working on the documentation of the setup, all parameters and steps to set it up, can definitely share it all with you once im done |
Yeah, add that block to the jwt plugin...you should then see 40X response if you send in a bearer token that's not valid instead of a redirect from the oidc plugin. Probably best to put the jwt plugin before the oidc plugin as well.. |
Also note that if the authorization header with bearer is not present the plugin will be skipped and go straight to oidc in your case.. |
Noted, ill try that out.....
and it should be all good...? ~It seems to work |
See the current example in the readme, you also need to set the |
Super 👍 |
I recommend reading this to understand some of the considerations with oidc: https://github.com/travisghansen/external-auth-server/blob/master/OAUTH_PLUGINS.md |
SetupWe are about to take you onto a journey... a long lasting adventure ~with ups' downs' and and a little bit of personal growth. In this tutorial we'll be setting up a star-constallation of three interconnected micro-services that will enable SSO.
Setup a database for keycloakRepo OIDC/Oauth2 Provider:
Before we get going on setting up anything, we need a place to percist data for keycloak, so that multiple instances can run. If you have a db, you can use that one, thats fine.... otherwise go ahead and set one up now. Create:
Open keycloak_values.yaml and edit the following fields to match your setup:
Set also set a default username and password for the admin user of keycloak:
Next set host and tls for dashboard:
Note this many not get an appropriate https cert unless cert-manager and an ngnix ingress controller are in place. Also, you probaly wanna put a theme onto the login page of the keycloak. Well i got some stuff for you then. Use:
Now you are all ready to go... Setup keycloak as an SSO authentication providerTo install keycloak simply run:
You can port forward to the service using:
Now login go to admin console and login with keycloak user. This configuration by default happens in the
Keycloak done! Setup external-auth-server eas:
Setup TraefikTraefik is available from:
Before you start deploying this, there are a few things you will need Traefik has a dashboard for overview of endpoint to secure it, add the following to the values:
In addition i have added configuration to support SSL to traefik_values.yaml:
Once ready run:
NOTE THE --version 1.61.0 (i could not get it working with current version) theres a ticket open and people are working on it. See this
Configure ingressUse the following to track the state of the traefik deployment:
Once the traefik services' ip no longer says PENDING and has an ip, it is time to set-up the dns. Go to your dns provider. I believe we're using transip.nl ;) Test that it is workingYou can try and navigate to the dashboard page for Traefik or you can be fancy and test the JWT plugin by running this py script:
|
That's a lot to digest! I'll share a few comments on the
Thanks for sharing your setup! |
In addition, this is just an example, i do not think securing infrastructure (as i did) with oidc makes sense, unless roles and or different clients get set up in keycloak to differentiate what different users have access to.
|
Hey Travis, |
There is a powerful assertion engine that can be used to run assertions against the various tokens for both oidc and jwt. With keycloak you could send group membership down for example and have eas deny access based on groups or any other arbitrary data point (claims in jwt parlance). I haven't documented the ambassador stuff but it would be good to get feedback regardless. Just setup your auth service as you did previously but use the file below to generate your prefix: https://github.com/travisghansen/external-auth-server/blob/master/bin/generate-ambassador-prefix.js Let me know how it goes. Given ambassador's limitations you can only have 1 configuration/token per auth service/'cluster' which may be quite inhibiting.. |
Kweel.... i'll try that out as well... in the meantime i got secure tls connection between gRCP-client and traefik and regular http/2 connection between traefik and gRPC micro-service with OIDC authentication going so thats done :) |
Very good! |
Do you want doc on that as well...? |
Sure. |
To get the ingress going i added:
Which made the traefik frontend and backend communicate with HTTP/2 or h2c.
In addition just so other people can find it (because i could not), to establish a secure connection from gRPC with a server and validating the servers certificate i used grpc.ssl_channel_credentials():
However it is also necessary to add ssl enforced on the Traefik configuration |
hi @travisghansen, I tried reading and following this huge thread to get ambassador working with Identity Server 4 (oidc). I am getting 403 with the following error and nothing in aes logs even with silly log level, so I guess ambassador can't reach it. Here is log from ambassador:
Here is my config for eas (I used
I've found your project somewhere in DEX issues if I am not mistaken and decided to give it a try hoping it support group claims and maybe custom claims with oidc (DEX doesn't dexidp/dex#1065). We may decide to use Istio ingress, so can help you with testing that as well, but spent some time with Ambassador so would like to get it working (hoping you are interested in that as well to have more material for docs/use cases )
|
@mlushpenko generally looks like you're on the right track, do you have any logs from the auth service containers you can send? I think istio does the same overlay behavior as ambassador (meaning, I don't think ambassador is doing anything special to the envoy config) so hypothetically running in instio would be the same general idea (I may rename the route if that thinking is correct but I don't have much experience with istio/envoy). It may be good to open another issue too, as you said this is quite long. I simply left it open until I commit support for jwks in the jwt plugin :) |
I've implemented jwks, probably snapping a new release this week. |
|
HI, It might be off topic, but I need to check one thing. |
@vishalgoel1988 yes eas can handle that scenario (and even more complex if you wanted to add basic auth backed by ldap as a 3rd option which is what I do). This comment has a pretty good overview of how it can be achieved: #16 (comment) Basically you want to simply add additional plugins to your config token and then optionally (and recommended) target those plugins with the pcb functionality. I’d recommend opening a new issue if you need help with your specific configuration and we’ll get you all up and going :) |
@vishalgoel1988 also note, if your primary app is a SPA then there are a couple of special options you should set especially if you own/develop the app and can add some logic there to better interact with eas. |
Thanks @travisghansen , I will give it a try |
Hi,
So my setup is:
Ambassador v: 0.72.0
Keycloak v: 5.0.0
And external-auth-server as middle-ware providing openid-connect authentication to a webservice.
I followed the setup first for the Traefik example, substituting config where it was needed.
My configuration for the external-auth-server values.yaml looks as follows:
In addition i made a couple of changes to the service.yaml to accommodate ambassadors annotation-based configuration.... These looks like this:
I managed to create a CONFIG_TOKEN for the keycloak.
The configuration for the plugin added to generate-config-token.js that i used was:
However, here comes the part on which i got stuck. The examples provided in this repo uses Traefik configuration and adds this to the
However, since we are using ambassador this is not an option.
So I expect I need to mount the configuration into a secret with the env adapter.
Which i tried without any luck.
So i tried adding the following to my values.yaml
Can you maybe help me out with this configuration :)
Then i can maybe help with writing some documentation :P
The text was updated successfully, but these errors were encountered: