Skip to content

Conversation

@GuentherJulian
Copy link
Contributor

@GuentherJulian GuentherJulian commented Jun 17, 2021

Integration of Istio and Keycloak features

Copy link
Member

@hohwille hohwille left a 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???

@hohwille
Copy link
Member

@GuentherJulian is this PR incomplete as you prefixed it with WIP:?
BTW: This is github and not gitlab, next time please use this github feature: https://github.blog/2019-02-14-introducing-draft-pull-requests/

@GuentherJulian
Copy link
Contributor Author

@GuentherJulian is this PR incomplete as you prefixed it with WIP:?
BTW: This is github and not gitlab, next time please use this github feature: https://github.blog/2019-02-14-introducing-draft-pull-requests/

@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.
I will convert it in draft and let you know when it is ready.

@GuentherJulian GuentherJulian self-assigned this Jun 22, 2021
@GuentherJulian GuentherJulian marked this pull request as draft June 22, 2021 08:10
@GuentherJulian GuentherJulian changed the title WIP: istio and keycloak integration istio and keycloak integration Jun 22, 2021
@GuentherJulian GuentherJulian marked this pull request as ready for review June 23, 2021 12:58
@GuentherJulian
Copy link
Contributor Author

@hohwille Can you check this PR again? I have added an example showing the validation of JWTs in Istio and within the application.

@GuentherJulian GuentherJulian requested a review from hohwille June 23, 2021 13:03
```
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)
Copy link
Contributor

@lilliCao lilliCao Jun 24, 2021

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.

Copy link
Contributor Author

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.

@lilliCao
Copy link
Contributor

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

@hohwille
Copy link
Member

hohwille commented Jul 5, 2021

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.

Copy link
Member

@hohwille hohwille left a 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.

Comment on lines +7 to +8
=== 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.
Copy link
Member

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.

Comment on lines +23 to +31
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.
Copy link
Member

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?

Comment on lines +33 to +40
=== 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
```
Copy link
Member

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?

Copy link
Member

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.

Copy link
Member

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.

Comment on lines +48 to +63
=== 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
Copy link
Member

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.

Comment on lines +17 to +18
@Inject
JsonWebToken jwt;
Copy link
Member

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");
Copy link
Member

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" })
Copy link
Member

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...

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

Successfully merging this pull request may close these issues.

3 participants