Skip to content

Commit

Permalink
Make use of jwt token for authentication
Browse files Browse the repository at this point in the history
depends on change in flock-eco to allow 'other' type
  • Loading branch information
ZzAve committed Jun 17, 2023
1 parent 0b30203 commit 88d3748
Show file tree
Hide file tree
Showing 20 changed files with 498 additions and 230 deletions.
12 changes: 12 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

PUBLIC_APP_HOST=workday.flock.local:8081
PUBLIC_APP_URL=http://$PUBLIC_APP_HOST

PUBLIC_ACCOUNTS_HOST=accounts.flock.local:8081
PUBLIC_ACCOUNTS_URL=http://$PUBLIC_ACCOUNTS_HOST
ACCOUNTS_SELFSERVICE_URL=$PUBLIC_ACCOUNTS_URL/ui/

PUBLIC_KRATOS_URL=http://$PUBLIC_ACCOUNTS_HOST/api

INTERNAL_KRATOS_URL=http://kratos:4433
INTERNAL_ADMIN_KRATOS_URL=http://kratos:4434
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ secrets.yml
node_modules
coverage
.env
/docker/kratos/identities/existing_identities.json
64 changes: 33 additions & 31 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
version: "3.9"
services:
workday:
image: gcr.io/flock-eco/flock-eco-workday-develop:snapshot
environment:
- GOOGLE_APPLICATION_CREDENTIALS=/tmp/keys/application_default_credentials.json
volumes:
- type: bind
source: $HOME/.config/gcloud/application_default_credentials.json
target: /tmp/keys/application_default_credentials.json
read_only: true
ports:
- "8080:8080"
networks:
- intranet
# workday:
# image: gcr.io/flock-eco/flock-eco-workday-develop:snapshot
# environment:
# - GOOGLE_APPLICATION_CREDENTIALS=/tmp/keys/application_default_credentials.json
# volumes:
# - type: bind
# source: $HOME/.config/gcloud/application_default_credentials.json
# target: /tmp/keys/application_default_credentials.json
# read_only: true
# ports:
# - "8080:8080"
# networks:
# - intranet

oathkeeper:
image: oryd/oathkeeper:v0.40.2
depends_on:
- kratos
- kratos-selfservice-ui-node
- kratos-setup-users
# - workday
ports:
- "8081:4455"
- "4456:4456"
command: serve proxy -c "/etc/config/oathkeeper/config.yaml"
environment:
- LOG_LEVEL=debug
- ERRORS_HANDLERS_REDIRECT_CONFIG_TO=$SELFSERVICE_URL/login
- SERVE_PROXY_CORS_ALLOWED_ORIGINS_0=$PUBLIC_INGRESS_URL
- SERVE_PROXY_CORS_ALLOWED_ORIGINS_1=$SELFSERVICE_URL
- ERRORS_HANDLERS_REDIRECT_CONFIG_TO=$ACCOUNTS_SELFSERVICE_URL/login
- MUTATORS_ID_TOKEN_CONFIG_ISSUER_URL=$PUBLIC_ACCOUNTS_URL
- SERVE_PROXY_CORS_ALLOWED_ORIGINS_0=$PUBLIC_APP_URL
- SERVE_PROXY_CORS_ALLOWED_ORIGINS_1=$ACCOUNTS_SELFSERVICE_URL
- SERVE_PROXY_CORS_ALLOWED_ORIGINS_2=$PUBLIC_KRATOS_URL
restart: on-failure
networks:
Expand Down Expand Up @@ -63,19 +65,19 @@ services:
- DSN=postgres://kratos:secret@postgres-kratos:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
#
- SERVE_PUBLIC_BASE_URL=$PUBLIC_KRATOS_URL
- SERVE_ADMIN_BASE_URL=$ADMIN_KRATOS_URL_INTERNAL
- SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=$PUBLIC_INGRESS_URL
- SELFSERVICE_ALLOWED_RETURN_URLS_0=$PUBLIC_INGRESS_URL
- SELFSERVICE_ALLOWED_RETURN_URLS_1=$SELFSERVICE_URL
- SERVE_ADMIN_BASE_URL=$INTERNAL_ADMIN_KRATOS_URL
- SELFSERVICE_DEFAULT_BROWSER_RETURN_URL=$PUBLIC_APP_URL
- SELFSERVICE_ALLOWED_RETURN_URLS_0=$PUBLIC_APP_URL
- SELFSERVICE_ALLOWED_RETURN_URLS_1=$ACCOUNTS_SELFSERVICE_URL
# - BASE_PATH=/kratos
- SELFSERVICE_FLOWS_ERROR_UI_URL=$SELFSERVICE_URL/error
- SELFSERVICE_FLOWS_SETTINGS_UI_URL=$SELFSERVICE_URL/settings
- SELFSERVICE_FLOWS_RECOVERY_UI_URL=$SELFSERVICE_URL/recovery
- SELFSERVICE_FLOWS_VERIFICATION_UI_URL=$SELFSERVICE_URL/verification
- SELFSERVICE_FLOWS_LOGOUT_UI_URL=$SELFSERVICE_URL/logout
- SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=$PUBLIC_INGRESS_URL
- SELFSERVICE_FLOWS_LOGIN_UI_URL=$SELFSERVICE_URL/login
- SELFSERVICE_FLOWS_REGISTRATION_UI_URL=$SELFSERVICE_URL/registration
- SELFSERVICE_FLOWS_ERROR_UI_URL=$ACCOUNTS_SELFSERVICE_URL/error
- SELFSERVICE_FLOWS_SETTINGS_UI_URL=$ACCOUNTS_SELFSERVICE_URL/settings
- SELFSERVICE_FLOWS_RECOVERY_UI_URL=$ACCOUNTS_SELFSERVICE_URL/recovery
- SELFSERVICE_FLOWS_VERIFICATION_UI_URL=$ACCOUNTS_SELFSERVICE_URL/verification
- SELFSERVICE_FLOWS_LOGOUT_UI_URL=$ACCOUNTS_SELFSERVICE_URL/logout
- SELFSERVICE_FLOWS_LOGOUT_AFTER_DEFAULT_BROWSER_RETURN_URL=$PUBLIC_APP_URL
- SELFSERVICE_FLOWS_LOGIN_UI_URL=$ACCOUNTS_SELFSERVICE_URL/login
- SELFSERVICE_FLOWS_REGISTRATION_UI_URL=$ACCOUNTS_SELFSERVICE_URL/registration
ports:
- '4433:4433'
- '4434:4434'
Expand All @@ -92,7 +94,7 @@ services:
kratos-selfservice-ui-node:
image: oryd/kratos-selfservice-ui-node:latest
environment:
- KRATOS_PUBLIC_URL=$PUBLIC_KRATOS_URL_INTERNAL
- KRATOS_PUBLIC_URL=$INTERNAL_KRATOS_URL
- KRATOS_BROWSER_URL=$PUBLIC_KRATOS_URL
- BASE_PATH=/ui
networks:
Expand Down Expand Up @@ -135,7 +137,7 @@ services:
command: migrate sql -e --yes -c /etc/config/kratos/kratos.yml

kratos-setup-users:
image: curlimages/curl
image: atlassian/default-image:4 # TODO let's go leaner
depends_on:
- kratos
networks:
Expand All @@ -144,7 +146,7 @@ services:
- type: bind
source: ./docker/kratos/identities
target: /tmp
command: sh /tmp/import_identities.sh
command: /tmp/import_identities.sh

keto-migrate:
image: oryd/keto:v0.11.1-alpha.0
Expand Down
12 changes: 8 additions & 4 deletions docker/kratos/identities/import_identities.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#!/bin/bash
#!/bin/sh

sleep 3

while read line; do
curl --request POST -vvv -sL \
--fail \
--header "Content-Type: application/json" \
--data-binary "@$line" http://kratos:4434/admin/identities
done < <(find . -type f -name "*.json")


done < <(find /tmp -type f -name "*.json")
echo $PWD
curl -vvv \
--header "Accept: application/json" \
http://kratos:4434/admin/identities | jq '[.[] | {"id": .id, "email": .traits.email} ] ' > /tmp/existing_identities.json
17 changes: 17 additions & 0 deletions docker/oathkeeper/accounts-management-rules.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
- id: oathkeeper-jwks
version: v0.40.2
upstream:
url: http://oathkeeper:4456
match:
url: http://accounts.flock.local:8081/.well-known/jwks.json
methods:
- GET
authenticators:
- handler: noop
authorizer:
handler: allow
mutators:
- handler: noop
errors:
- handler: redirect

- id: kratos-public-api
version: v0.40.2
upstream:
Expand Down
8 changes: 8 additions & 0 deletions docker/oathkeeper/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ errors:
verbose: true

mutators:
id_token:
# Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.
enabled: true
config:
issuer_url: --set-me-through-env-variable--
jwks_url: file:///etc/config/oathkeeper/jwks.json
ttl: 60s
claims: '{"aud": ["https://my-backend-service/some/endpoint"],"email": "{{ print .Extra.identity.traits.email }}"}'
header:
enabled: true
config:
Expand Down
18 changes: 18 additions & 0 deletions docker/oathkeeper/jwks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"keys": [
{
"use": "sig",
"kty": "RSA",
"kid": "75ab2a62-5eeb-4362-8a23-6aa8e0622f4d",
"alg": "RS256",
"n": "u6cx6cF08Jqavfl5Mrh8_KBDXkBu-g6aY1SZsxy31ac_9iZgI3YgEkqkFqO4AvDG8fIydU8BINbbxtvDe6bgTXdagKAshsgqTHLRIrv0gPX7ZEeAU-dahP1dsWtmmgmNCzduPn8N8LBkQuj9DifGKihGr8E7LjcuGx6rvaxpsrl-bQZ5TxKZRq3CkB-vXJM8nXn48hlWwRZ8AcAUcazJFbao5xD0ejzgL1WDndXPix2u_Twl6zDZ8BlMmUKmPQUr9voWLA0CZbmpF3Temp6ENW20ngucrv1MsWE65MQnFqnt5bnlL30OJWdV3u280Dqchhr1b5CtNOdB0lzzGdmVuw",
"e": "AQAB",
"d": "qPy1_DXVI192_qGMvVpaY_3G7TfFOLax3cWv7BZujp7hAMAqT4Tu-Mny3thsu2ktH3Dmc7HD6FjU7k21ysLKt7hF7hNQRcg4H0Q-hbMRSpk53GJvdB-h6qVoHIAFk64KMBGo2-r7GMcgYwkB6h9zWz-N-HRg4QucH5wNOO_s9556GHe5tRVuz4YsaF0XdLXS5bPLgkAtVZhE_4KCaAaZJL4aV35zBc2HMKZ059L3H2RnPQtloEDUDbeDPPZKwUBCBhGNQvz6GkaYn-sdgIQnHv374RfXDHga2_qDKBbNIKno9F59tt5ytijrtqnJGovAMnmT4bAn7ExpUw0tMfC7gQ",
"p": "wVwk9tRW5w4PTyRuo5eYvmgRmfDUFWYreQCweHkKNT92EPUlJQevKcfvKc8DM2CH3T6o3KVvuNVq4JUsPAFh7MWW_V_H_HDZQ6Q0iAyb6mTrSdAjHrnTY9MHc-aDSKfuneXY_e3-ag-0gmMBng7Bu0PxomWZZHhWZ7aclAEitBs",
"q": "-HHEhBkjuycQg6ZdbOP4SFHQ_X6CQNXrHP8RWnYpnwFCV1vnccUxOHsaXZkJSVU1ibLD9eU_iTtR3F4zPFEEmIM5JVuBvLJcHqqBbEDYPabPoefAz3yqzUEw-yWG2O9JaD7u4zl-zr9R6ieMYV0IyGuGvRkPk6MnhJSsr6RcfuE",
"dp": "NT7pkurwL1pIzvNqYDQ7xJsl1a1iya3D5ONStSonrHgYTB0lqGfQTYIYEvxFll1LrJo3p-MKu-xRLR0G_FMpIylaJdW9XX-55I2QRbKrMMWvoTjmouxrEL8o-zqMBnLwG50SvwJNn-lJPOqEpIDNyoKwRJcTwX391TuNLJiPdOc",
"dq": "F_8VFhU_iEIbrDuTZoMWZhXQ88sWVaDT1rckO_KRzpPWjo2H60s6l9P8FfJEHVsnkqc7mjKMUnrySzCmDjtdEEYMbPlLrKglkaiyW3xf5oSIJYE29FN8Q9r6GifjwGxMUM9TT4ssHlgIV29-daEAyirolrcm9AGcPYgGrehYLsE",
"qi": "fjD-SuFpHe3xgk-1SDtjV19QtbFmchjoGuWA5A9SPiA-L3471uv9mI5zil-GS54URtuVBd6QZ404zBR7cuc9VnUHE5k_avKfQh0O4uIkOF7o7TMPf8xc3d4Uee2uKvJsASQw9rNcwtpqKSismxTNE86SoTa8zEYjYDdgYr81zTE"
}
]
}
106 changes: 6 additions & 100 deletions docker/oathkeeper/rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,106 +17,12 @@
handler: allow
mutators:
- handler: header
errors:
- handler: redirect

- id: echo-public
version: v0.40.2
match:
url: http://localhost:8085/<.*>
methods:
- GET
authenticators:
- handler: anonymous
authorizer:
handler: allow
mutators:
- handler: header
errors:
- handler: redirect
- id: echo-public
version: v0.40.2
match:
url: https://<.*>.gitpod.io/echo/public/<.*>
methods:
- GET
authenticators:
- handler: anonymous
authorizer:
handler: allow
mutators:
- handler: header
errors:
- handler: redirect
- id: echo-protected
version: v0.40.2
match:
url: https://<.*>.gitpod.io/echo/protected/<.*>
methods:
- GET
authenticators:
- handler: cookie_session
authorizer:
handler: allow
mutators:
- handler: header
errors:
- handler: redirect
- id: echo-elevated-authentication
version: v0.40.2
match:
url: https://<.*>.gitpod.io/echo/elevated/<.*>
methods:
- GET
authenticators:
- handler: cookie_session
- handler: id_token
config:
check_session_url: http://kratos-whoami-aal-aware:8080/sessions/whoami?aal=aal2
authorizer:
handler: remote_json
config:
remote: http://keto:4466/relation-tuples/check
payload: '{ "namespace": "access", "object": "{{printIndex .MatchContext.RegexpCaptureGroups
1}}", "relation": "read", "subject_id": "{{print .Subject}}" }'
mutators:
- handler: header
errors:
- handler: redirect
config:
to: https://8085-flockcommun-identityacc-995ctfvg8og.ws-eu96b.gitpod.io/kratos/self-service/login/browser?refresh=true&aal=aal2
- id: echo-keto-get-vehicles
version: v0.40.2
match:
url: https://<.*>.gitpod.io/echo/vehicles/<.*>
methods:
- GET
authenticators:
- handler: cookie_session
authorizer:
handler: remote_json
config:
remote: http://keto:4466/relation-tuples/check
payload: '{ "namespace": "access", "object": "{{printIndex .MatchContext.RegexpCaptureGroups
1}}", "relation": "read", "subject_id": "{{print .Subject}}" }'
mutators:
- handler: header
errors:
- handler: redirect
- id: echo-keto-get-finances
version: v0.40.2
match:
url: https://<.*>.gitpod.io/echo/finances/<.*>
methods:
- GET
authenticators:
- handler: cookie_session
authorizer:
handler: remote_json
config:
remote: http://keto:4466/relation-tuples/check
payload: '{ "namespace": "access", "object": "{{printIndex .MatchContext.RegexpCaptureGroups
1}}", "relation": "read", "subject_id": "{{print .Subject}}" }'
mutators:
- handler: header
claims: |
{
"aud": ["http://workday.flock.local:8081"],
"email": "{{ print .Extra.identity.traits.email }}"
}
errors:
- handler: redirect
Binary file added docs/Workday App permissions model.drawio.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions docs/authentication-and-authorization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Authentication and Authorization

The intended target state for Workday is to extract all forms of Authentication and Authorization from the spring boot
and or react application, but rather make use of an identity aware proxy (Ory's Oathkeeper) to make such decisions.

This means that all incoming requests to the Spring Boot application are expected to be authenticated, and authorised,
such that the application can focus on the functional logic solely.

## Roadmap

1. Setup authentication model in `flock-iam` project
2. Authentication via Ory's Kratos
3. 'Simpler' `GET` and `PUT` endpoints authorization
4. `POST` / create endpoint
5. List endpoints
6. Removal of authorities from workday app itself

## Workday's permission model

[Ory's keto](https://www.ory.sh/docs/keto/) make use of a permission model, to determine whether a given subject (a
User) can access an object (e.g. a Workday, a Holiday, etc.). A permission model consists of two parts: a relation
model, and the derived permissions from said these relations.

Below you'll find the initial _relations model_ for Workday.
![x](Workday%20App%20permissions%20model.drawio.png)

Which can be read as

- A _Person_ is the **owner** of a _Workday_
- A _User_ is the **owner** of a _Person_
- A _Flock_ is the **organisational unit** of a _Person_
- A _Flock_ is the **organisational unit** of a _Flock_
- A _User_ is the **manager** of a _Flock_
- etc.

> ℹ️
> This model allows manager of (a) Flock. to have a relation with a specific Workday coupled to a person.
>
> E.g. _Workday-X_ is **owned** by _Person-Y_, which is part of **organisational unit** _Flock-Z_, which in turn is **managed** by _User-manager-A_
## Understanding the Ory stack

(probably best to move me to flock-iam related repo?)

There are multiple components to the Ory stack

- Kratos, ...
- Oathkeeper, ...
- Keto, ...

## Develop parts here

To generate a `jwks.json` file:

```bash
docker run oryd/oathkeeper:v0.40.3 credentials generate --alg RS256 > jwks.json
```

- Something docker compose
- Something linking Kratos identities to Workday Users
Binary file added docs/oathkeeper-decision-engine.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gcp-starter-sql-postgresql</artifactId>
Expand Down
Loading

0 comments on commit 88d3748

Please sign in to comment.