Implementacja DEX

This commit is contained in:
Aleksander Cynarski 2020-10-15 23:08:04 +02:00
parent 5b634a1141
commit 1471893c2f
7 changed files with 266 additions and 34 deletions

View File

@ -12,17 +12,32 @@ W tym etapie wprowadzimy nowy request zabezpieczony tokenem JWT:
```mermaid
sequenceDiagram
Użytkownik->>KrakenD: /jwt_access <br/>[Authorizaion: Bearer token]
KrakenD->>Hydra: .well-known/jwks.json
Hydra-->>KrakenD: jwk
KrakenD->>DEX: dex/keys
DEX-->>KrakenD: jwk
KrakenD-->>KrakenD: validator <br/>[issuer]
KrakenD->>Backend: /users/1.json
Backend-->>KrakenD: response_0
KrakenD->>+Użytkownik: Response
```
Dodatkowy scope `groups`
```mermaid
sequenceDiagram
Użytkownik->>KrakenD: /jwt_access_admin <br/>[Authorizaion: Bearer token]
KrakenD->>DEX: dex/keys
DEX-->>KrakenD: jwk
KrakenD-->>KrakenD: validator <br/>[issuer, groups: admins]
KrakenD->>Backend: /users/1.json
Backend-->>KrakenD: response_0
KrakenD->>+Użytkownik: Response
```
Flow jest typowo testowy, na razie nie ma revoke jwt, a samo pobranie tokenu należy zrobić za pomocą pliku `Makefile`.
Przykład wykorzystania KrakenD do zabezpieczenia bakendu za pomocą JWT:
[![asciicast](https://asciinema.org/a/Py3dbR2m5Jt3FdhGI7eINtpdu.png)](https://asciinema.org/a/Py3dbR2m5Jt3FdhGI7eINtpdu)

109
dex/config-dev.yaml Normal file
View File

@ -0,0 +1,109 @@
# The base path of dex and the external name of the OpenID Connect service.
# This is the canonical URL that all clients MUST use to refer to dex. If a
# path is provided, dex's HTTP service will listen at a non-root URL.
issuer: http://127.0.0.1:5556/dex
# The storage configuration determines where dex stores its state. Supported
# options include SQL flavors and Kubernetes third party resources.
#
# See the storage document at Documentation/storage.md for further information.
storage:
type: postgres
config:
host: postgresd
port: 5432
database: dex
user: dex
password: postgres
ssl:
mode: disable
# Configuration for the HTTP endpoints.
web:
http: 0.0.0.0:5556
# Uncomment for HTTPS options.
# https: 127.0.0.1:5554
# tlsCert: /etc/dex/tls.crt
# tlsKey: /etc/dex/tls.key
# Configuration for telemetry
telemetry:
http: 0.0.0.0:5558
# Uncomment this block to enable the gRPC API. This values MUST be different
# from the HTTP endpoints.
# grpc:
# addr: 127.0.0.1:5557
# tlsCert: examples/grpc-client/server.crt
# tlsKey: examples/grpc-client/server.key
# tlsClientCA: /etc/dex/client.crt
# Uncomment this block to enable configuration for the expiration time durations.
# expiry:
# deviceRequests: "5m"
# signingKeys: "6h"
# idTokens: "24h"
# Options for controlling the logger.
# logger:
# level: "debug"
# format: "text" # can also be "json"
# Default values shown below
# oauth2:
# use ["code", "token", "id_token"] to enable implicit flow for web-only clients
# responseTypes: [ "code" ] # also allowed are "token" and "id_token"
# By default, Dex will ask for approval to share data with application
# (approval for sharing data from connected IdP to Dex is separate process on IdP)
# skipApprovalScreen: false
# If only one authentication method is enabled, the default behavior is to
# go directly to it. For connected IdPs, this redirects the browser away
# from application to upstream provider such as the Google login page
# alwaysShowLoginScreen: false
# Uncommend the passwordConnector to use a specific connector for password grants
# passwordConnector: local
# Instead of reading from an external storage, use this list of clients.
#
# If this option isn't chosen clients may be added through the gRPC API.
staticClients:
- id: example-app
redirectURIs:
- 'http://127.0.0.1:5555/callback'
name: 'Example App'
secret: ZXhhbXBsZS1hcHAtc2VjcmV0
# - id: example-device-client
# redirectURIs:
# - /device/callback
# name: 'Static Client for Device Flow'
# public: true
connectors:
- type: mockCallback
id: mock
name: Example
# - type: google
# id: google
# name: Google
# config:
# issuer: https://accounts.google.com
# # Connector config values starting with a "$" will read from the environment.
# clientID: $GOOGLE_CLIENT_ID
# clientSecret: $GOOGLE_CLIENT_SECRET
# redirectURI: http://127.0.0.1:5556/dex/callback
# hostedDomains:
# - $GOOGLE_HOSTED_DOMAIN
# Let dex keep a list of passwords which can be used to login to dex.
enablePasswordDB: true
# A static list of passwords to login the end user. By identifying here, dex
# won't look in its underlying storage for passwords.
#
# If this option isn't chosen users may be added through the gRPC API.
staticPasswords:
- email: "admin@example.com"
# bcrypt hash of the string "password"
hash: "$2a$10$2b2cU8CPhOTaGrs1HRQuAueS7JTT5ZHsHSzYiFPm1leZck7Mc8T4W"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"

55
dex/config-ldap.yaml Normal file
View File

@ -0,0 +1,55 @@
issuer: http://127.0.0.1:5556/dex
storage:
type: postgres
config:
host: postgresd
port: 5432
database: dex
user: dex
password: postgres
ssl:
mode: disable
connectors:
- type: ldap
name: OpenLDAP
id: ldap
config:
host: ldap:389
insecureNoSSL: true
bindDN: cn=admin,dc=example,dc=org
bindPW: admin
usernamePrompt: Email Address
userSearch:
baseDN: ou=People,dc=example,dc=org
filter: "(objectClass=person)"
username: mail
idAttr: DN
emailAttr: mail
nameAttr: cn
groupSearch:
baseDN: ou=Groups,dc=example,dc=org
filter: "(objectClass=groupOfNames)"
userMatchers:
- userAttr: DN
groupAttr: member
nameAttr: cn
web:
http: 0.0.0.0:5556
staticClients:
- id: example-app
redirectURIs:
- 'http://127.0.0.1:5555/callback'
name: 'Example App'
secret: ZXhhbXBsZS1hcHAtc2VjcmV0

0
dex/dex.db Executable file
View File

View File

@ -14,45 +14,36 @@ services:
ports:
- "8000:8080"
hydra-migrate:
image: oryd/hydra:v1.8.5
environment:
- DSN=postgres://hydra:secret@postgresd:5432/hydra?sslmode=disable&max_conns=20&max_idle_conns=4
command:
migrate sql -e --yes
restart: on-failure
ldap:
image: osixia/openldap:1.4.0
command: ["--copy-service"]
volumes:
- ./ldap/config-ldap.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/config-ldap.ldif
ports:
- 389:389
- 636:636
postgresd:
image: postgres:9.6
ports:
- "5432:5432"
environment:
- POSTGRES_USER=hydra
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=hydra
- POSTGRES_USER=dex
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=dex
hydra:
image: oryd/hydra:v1.8.5
dex:
image: quay.io/dexidp/dex:latest
command: ["serve", "/config/config-ldap.yaml"]
volumes:
- ./dex:/config
ports:
- "4444:4444" # Public port
- "4445:4445" # Admin port
- "5555:5555" # Port for hydra token user
command:
serve all --dangerous-force-http
env_file: ./.env
restart: unless-stopped
- 5556:5556
- 5558:5558
depends_on:
- hydra-migrate
consent:
#image: oryd/hydra-login-consent-node:latest
image: paramah/consent:latest
environment:
- HYDRA_ADMIN_URL=http://hydra:4445
- BASE_URL=http://consent.service.consul:3000
ports:
- "3000:3000"
restart: unless-stopped
- postgresd
- ldap
kraken:
image: devopsfaith/krakend:config-watcher

View File

@ -84,8 +84,26 @@
"extra_config": {
"github.com/devopsfaith/krakend-jose/validator": {
"alg": "RS256",
"issuer": "http://127.0.0.1:4444/",
"jwk-url": "http://hydra:4444/.well-known/jwks.json",
"issuer": "http://127.0.0.1:5556/dex",
"jwk-url": "http://dex:5556/dex/keys",
"disable_jwk_security": true
}
}
},
{
"endpoint": "/jwt_access_admin",
"backend": [
{
"url_pattern": "/users/1.json"
}
],
"extra_config": {
"github.com/devopsfaith/krakend-jose/validator": {
"alg": "RS256",
"issuer": "http://127.0.0.1:5556/dex",
"jwk-url": "http://dex:5556/dex/keys",
"roles_key": "groups",
"roles": ["admins"],
"disable_jwk_security": true
}
}

44
ldap/config-ldap.ldif Normal file
View File

@ -0,0 +1,44 @@
# Already included in default config of Docker image osixia/openldap:1.4.0.
#
# dn: dc=example,dc=org
# objectClass: dcObject
# objectClass: organization
# o: Example Company
# dc: example
dn: ou=People,dc=example,dc=org
objectClass: organizationalUnit
ou: People
dn: cn=jane,ou=People,dc=example,dc=org
objectClass: person
objectClass: inetOrgPerson
sn: doe
cn: jane
mail: janedoe@example.com
userpassword: foo
dn: cn=john,ou=People,dc=example,dc=org
objectClass: person
objectClass: inetOrgPerson
sn: doe
cn: john
mail: johndoe@example.com
userpassword: bar
# Group definitions.
dn: ou=Groups,dc=example,dc=org
objectClass: organizationalUnit
ou: Groups
dn: cn=admins,ou=Groups,dc=example,dc=org
objectClass: groupOfNames
cn: admins
member: cn=john,ou=People,dc=example,dc=org
member: cn=jane,ou=People,dc=example,dc=org
dn: cn=developers,ou=Groups,dc=example,dc=org
objectClass: groupOfNames
cn: developers
member: cn=jane,ou=People,dc=example,dc=org