Open maybeec opened 3 years ago
KeyCloak needs to be discussed
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?
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
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.
Authentication should be implemented centrally at this time by keycloak.
We identified following options:
As a MVP, we will have to implement Authentication based on Keycload + Istio + JWT Authorization within Services.
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:
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.
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?