-
Notifications
You must be signed in to change notification settings - Fork 6
istio and keycloak integration #32
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
base: main
Are you sure you want to change the base?
istio and keycloak integration #32
Conversation
hohwille
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems as if only k8s configs have been added.
Assuming they have been tested and work, I approve this.
Anybody else active here giving feedback???
|
@GuentherJulian is this PR incomplete as you prefixed it with |
@hohwille It's not finished yet. I am still working on it and would like to add some additional features to be able to check permissions in code. |
|
@hohwille Can you check this PR again? I have added an example showing the validation of JWTs in Istio and within the application. |
| ``` | ||
| You will get an error message 401 Unauthorized. This is because this operation is secured with the role `demo-quarkus.SaveObject`. You can only access this operation if you pass a valid JWT token in the request header. So add the role to the user in Keycloak and run the following command to get the token. | ||
| ``` | ||
| TOKEN=$(curl -d 'client_id=demo-quarkus-cli' -d 'username=demo' -d 'password=demo' -d 'grant_type=password' 'http://keycloak-demo-quarkus.localhost/auth/realms/demo-quarkus/protocol/openid-connect/token' | jq ".access_token" -r) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
request token with client secret too. 'client_secret=7745de1c-a85e-4bfe-97fe-42dc2b0b3f65'. Without that, istio will return Jwks doesn't have key to match kid or alg from Jwt if authorization_policy.yaml is deployed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You only need to pass the client secret if 'Access Type' of the Keycloak client is set to confidential. In the json file of the realm, the client 'demo-quarkus-cli' is specified as public client.
|
Also, I personally think we should put the code in a separated branch instead of merging to main in case we want to test other stuffs with the ref application @GuentherJulian @hohwille |
Maintaining different branches in parallel does not work on the long run. In such case it is better to use a feature toggle but keep a single main branch maintained. |
hohwille
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@GuentherJulian thanks for this PR. 👍
You got the integration working and extended our sample app with some scenarios to test everything together in action.
If that was the task and goal of this PR all is fine.
With my background in devon4j I am always thinking further and already would like to shape what we need on the long run.
However, I am also happy that we can be agile, create some issues from the review comments and merge this PR as is.
First, have a look at my comments and try to see what makes sense for you and what you could address easily.
IMHO it is really important to have the OCX team on board and get their POV and review feedback as well.
| === Introducing Keycloak | ||
| https://www.keycloak.org/[Keycloak] is an opensource IAM (Identity and Access Management) solution with a broad set of features like SSO, authentication and authorization, social login, multifactor authentication etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from our experience in devon4j structuring documentation like this does not work out and is not maintainable.
Therefore my suggestion is:
- we create separate asciidoc files for keycloak and istio where we can document general aspects for each of them
- in file like this where we want to document the integration between those two we can link to each of them but shall IMHO not explain anything more but focus on the integration aspects.
| To create the cluster, we use k3d. First create a local Docker registry. | ||
| ``` | ||
| k3d registry create registry --port 5000 | ||
| ``` | ||
| The next step is to create the cluster. Navigate to the folder with the reference application and run the following command in your WSL environment. | ||
| ``` | ||
| k3d cluster create -c k8s/cluster-setup.yaml --k3s-server-arg '--no-deploy=traefik' | ||
| ``` | ||
| This will create a local Kubernetes cluster with one master and two worker nodes within your WSL environment. By default, k3d creates a Traefik proxy as an ingress controller. Since we will use the Istio Ingress Gateway later, we do not need it here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we really commit ourselves to k3d?
In the PR for devonfw-ide I suggested that we go for docker desktop.
In real environments we will always use kubernetes natively.
So if we locally work with k3d the guide only works locally and only if k3d is present...
I am happy to be told otherwise but why dont we describe this directly with kubectl?
| === Install Istio | ||
| The first step is to install Istio. You can find a https://istio.io/latest/docs/setup/getting-started/[Getting Started] guide and some sample applications on the Istio homepage. + | ||
| Navigate in your home directory and execute the following commands: | ||
| ``` | ||
| curl -L https://istio.io/downloadIstio | sh - | ||
| cd istio-1.10.0 | ||
| export PATH=$PWD/bin:$PATH | ||
| ``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to "install" istio natively on our machine?
Dont we run this as container as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Further such instruction also does not seem stable and maintainable.
When I was testing the version had meanwhile already changed and I had to do cd istio-1.10.2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Further if we just recommend to follow specific installation instructions from the web, we could simply link them:
https://istio.io/latest/docs/setup/getting-started/
This is already maintained and updated to the latest version.
So we can link instead of copying.
Otherwise we can think about full automation where it really makes sense or integration in devonfw-ide, etc. where suitable.
| === Build the application and create a Docker image | ||
| Now we need to build the application and the corresponding Docker image. Use Maven to build the application. | ||
| ``` | ||
| mvn clean package | ||
| ``` | ||
| If you want to create a native executable use: | ||
| ``` | ||
| mvn clean package -Pnative | ||
| ``` | ||
| If tests fail because of authorization configurations you can add `-Dmaven.test.skip=true` option to skip the tests. | ||
|
|
||
| Then we create a Docker image and push it into your local Docker registry, which was started by k3d. | ||
|
|
||
| ``` | ||
| docker build -f src/main/docker/Dockerfile.jvm . -t demo-quarkus | ||
| docker tag demo-quarkus k3d-registry:5000/demo-quarkus |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all this has nothing to do with the integration of keycloak and istio what this documentation should be about.
| @Inject | ||
| JsonWebToken jwt; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not familiar with this style so sorry for asking:
You are making the REST service @RequestScope so physically for each request an own instance is created and the JWT passed as HTTP parameter is injected into this stateful bean instead of passing it as method parameter?
I rahter find this a magical confusion but maybe this is quarkus best practice.
However, I do not get why then we receive SecurityContext as paramter than and the JWT as injection.
| if (ctx.getUserPrincipal() == null) { | ||
| name = "anonymous"; | ||
| } else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) { | ||
| throw new InternalServerErrorException("Principal and JsonWebToken names do not match"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is always good to assert things but is there any real reason how this could ever happen?
Sounds like inconsistency in quarkus itself if this case ever occurs...
|
|
||
| @GET | ||
| @Path("/roles-allowed/admin") | ||
| @RolesAllowed({ "admin" }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK. So like in spring we have the freedom to put @RolesAllowed annotation "everywhere" and it is just working via AOP. So next we could think about some best practices how to do it.
In devon4j we always annotated use-cases as one use-case may call another use-case.
Do we give up such principles in quarkus and let the users do whatever they like?
Will we then call functionality from one service method in another service method? What if @Context parameters are required that prevent such usage.
My experience was that the REST service is simply exposing functionality to the outside world but nothing more.
However, I am already discussing beyond the goal of this acutal PR...
Integration of Istio and Keycloak features