devonfw-forge / devonfw-microservices

Apache License 2.0
2 stars 7 forks source link

Access Control Conception #17

Open maybeec opened 3 years ago

maybeec commented 3 years ago

Authentication / Authorization

What needs to be done at which state? Authorization at application level or by naming conventions as part of the ingress configuration?

Authentication API / Module?

maybeec commented 3 years ago

KeyCloak needs to be discussed

matus-m commented 3 years ago

This (as several other issues in this list) can only be addressed within a fixed limited scope, or given a fixed list of assumptions - e.g. greenfield project with free choice of technologies. Any real-world engagement could introduce constraints or landscape that might render our solution completely obsolete - say a customer already has Auth infrastructure in place that Devon MS would need to adjust to, or has custom SSO, in house tooling...

So we should probably define the scope in which we are addressing this issue, for example: In context of Single Microservice:

In the context of full project/solution:

Or do you have any other suggestions how to turn this to an actionable item?

hohwille commented 3 years ago

JWT should be a common ground/match for our worlds. We support this OOTB with a starter in devonfw, you only need to configure it (mainly you just need the public key for auth verification, validity ranges can be customized in config). https://github.com/devonfw/devon4j/blob/master/documentation/guide-access-control.asciidoc https://github.com/devonfw/devon4j/blob/master/documentation/guide-jwt.asciidoc

The actual "human user authentication" should IMHO be abstracted away via some gateway. That gateway can be the IAM itself or a minimal microservice that integrates the IAM e.g. via SAMLv2, OpenIdConnect, etc. and finally issues JWT that will be added as Bearer Token to HTTP header when request is forwarded to the backend apps. Interesting discussions are if the client app (SPA, PWA, etc.) knows about this and has login screens and manages JWT (to also address CSRF) or if you also keep that out of your client and control the login in the gateway keeping more flexibility (e.g. to add 2FA, etc. without touching the microservices). As we are shifting from UI integration with iFrames to modern approaches (micro-portal) this can also be solved from the browser client as well. Anyhow we should stay flexible in this area but maybe we can discuss and align for one proposed best practice. https://github.com/devonfw-forge/enterprise/blob/master/documentation/access-control.asciidoc

matus-m commented 3 years ago

JWT auth is supported out-of-the-box by the MicroProfile JWT spec, provided in Quarkus by quarkus-smallrye-jwt extension. The validation can be done either using locally stored public key or simply by specifying a well know URL of HTTPS based JsonWebKey (JWK) - thus allowing to point directly to Keycloak or other Auth provider, without the need to embed keys into app.

Its integrated into CDI and RBAC, so you can inject current token, claims, current principal... etc in any bean and defined RBAC by standard annotations @RolesAllowed.

We are using it in production with Keycloak(RHSSO) without any issues so far.

maybeec commented 3 years ago

Authentication should be implemented centrally at this time by keycloak.

We identified following options:

  1. we build up authorization based on JWT, whereas all services should be able to validate the token by their own
  2. as the previous solution does not scale up in bigger systems, we also need to create a solution with a call back to get the permissions for a specific token for a specific application

As a MVP, we will have to implement Authentication based on Keycload + Istio + JWT Authorization within Services.

hohwille commented 3 years ago

The solution with quarkus-smallrye-jwt sounds great and I am fine with this dropping the custom devon4j-security-jwt stuff we have created for spring-boot. However, what I still see a very valuable concept from devo4j is the best-practice on access control: https://github.com/devonfw/devon4j/blob/master/documentation/guide-access-control.asciidoc#suggestions-on-the-access-model

Furhter I would love to discuss the following questions:

hohwille commented 3 years ago

IMHO a smarter idea could be that the micro-frontend / portal / API gateway gets all the permissions of the user but following conventions create individual JWTs per MS that only contain the according permissions required for that MS. For sub-sequent MS calls every JWT could contain a login/session specific ID so the gateway is able to cache all the JWTs and pick the proper one by this ID and the actual MS that is routed to. Following the simple namespacing concept we have suggested in devon4j this could be easy to implement. My concern is however, that we will go away from KISS and simple standards: Keycloak will not be able to solve this for us and we would need to implement custom logic in the gateway ourselves for this.