Authentication Overview
This document touches everything around the Authentication at ODJ. The Authorization part is covered in a dedicated Access Management documentation.
ODJ-Token proxy on apigee
The ojd-token
endpoint is a custom created Proxy implementation on Apigee and runs with Apigee SaaS with given high availability.
It supports currently the following auth flows:
- client_credential
- authorization_code (PKCE)
The discovery endpoint can be found here: https://live.api.schwarz/odj/oauth2/v1/.well-known/openid-configuration
The refresh_token
is prepared but not finalised and may be supported in the future too.
The different flows are backed by different IDP-Providers. While client-credentials are mainly targeted for machine-services
and therefore managed by MyAPI/Apigee we support for AzureAD Users of SIT also the Authorization Code flow. Please keep in mind
that an Azure Active Directory User within Schwarz still needs a certain Access Package grp-sit-int-pim-odj-access
to be able
to login.
- client_credential: Credentials from an MyAPI/Apigee Consumer App on the
production
environment. - authorization_code: via Azure Active Directory on Tenant
d04f4717-5a6e-4b98-b3f9-6918e0385f4c
with the custom configured Application (client) IDYQEqUZmXqfxMX2YZL0waD91zkF0Rr36O
Below in the graphic you can see the flow briefly reflected.
The successful execution of both Auth-Flows lead into a token issued by apigee over the odj-token proxy and have
https://live.api.schwarz/remote-token/token
as an Issuer. Due to the use of different IDPs in the background, issued tokens
also indicate their source within the subject having a suffix [aad|myapi]:identity
.
Example MyAPI-based JWT
{
"sub": "myapi:tCrHPmU8rfAUc1bYB1OqVRrCzVAE7etT",
"aud": "odj",
"api_product_list": [
"sit_odj-core_core-v1_prod"
],
"nbf": 1695309202,
"name": "live_odj-core_odj-scim-idp",
"iss": "https://live.api.schwarz/remote-token/token",
"exp": 1695311002,
"app_id": "e3bc85a9-1061-46da-9bce-1384c61418eb",
"iat": 1695309202,
"jti": "17634fa3-e49f-441a-b87d-024052819423"
}
Example AAD-based JWT
{
"sub": "aad:f66f4d25-dada-485d-8d8f-6fb6c5569fa4",
"aud": "odj",
"nbf": 1695323251,
"scope": "profile openid email offline_access",
"name": "Robert Hoppe",
"iss": "https://live.api.schwarz/remote-token/token",
"exp": 1695325051,
"iat": 1695323251,
"email": "robert.hoppe@tc1.io",
"jti": "d35d0f27-30e5-4309-983c-b4ecf4848d57"
}
UI driven Authentication flow
All UI components expects a cookie with odj_access_token
containing a valid JWT. The flow is explained
within the following graphic:
The User hits the Ingress-NGINX as the first component within the cluster. Using standard tools we enforce that the
cookie is set for all pages except the landing-page on /
.
...
annotations:
nginx.ingress.kubernetes.io/auth-signin: https://$host/authenticate?redirect_uri=$escaped_request_uri
nginx.ingress.kubernetes.io/auth-url: https://live.api.schwarz/odj/oauth2/v1/validate
nginx.ingress.kubernetes.io/auth-cache-key: $cookie_odj_access_token
nginx.ingress.kubernetes.io/auth-cache-duration: 200 202 204 302 5m
The NGINX does a sub-request and tries to validate the request with this call. Successful responses of the backend will be cached for 5m.
The validation is currently done by the ODJ-Token proxy at https://live.api.schwarz/odj/oauth2/v1/validate
which
supports JWT given as AUTHORIZATION
header or within a Cookie called odj_access_token
. The validation endpoint returns
a 401 on invalid calls (empty token, invalid, etc.) and 200 on valid calls which leads the NGINX to transfer the call
to the actual target backend.