Define WebSockets rules
This guide shows how to use Ory Oathkeeper with WebSockets.
WebSockets bypass Ory Oathkeeper after the first request and thus Ory Oathkeeper only validates cookies once. It is up to your service to make sure that WebSocket connections expire within a reasonable time frame so the session cookie is still active and valid.
Let's create a simple echo WebSocket service that sends back an accepted message. We'll use the Gin Web framework to build our application, and Ory Kratos to handle user login, sign-up, and verification flows.
Install Ory Kratos and Ory Oathkeeper
You can create any directory for testing and create a docker-compose.yml
file with the following content:
version: "3.7"
services:
oathkeeper:
image: oryd/oathkeeper:<version-you-want>
depends_on:
- kratos
ports:
- 8080:4455
- 4456:4456
command:
serve proxy -c "/etc/config/oathkeeper/oathkeeper.yml"
environment:
- LOG_LEVEL=debug
restart: on-failure
networks:
- intranet
volumes:
- ./oathkeeper:/etc/config/oathkeeper
postgres-kratos:
image: postgres:9.6
environment:
- POSTGRES_USER=kratos
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=kratos
networks:
- intranet
kratos-migrate:
image: oryd/kratos:<version-you-want>
links:
- postgres-kratos:postgres-kratos
environment:
- DSN=postgres://kratos:secret@postgres-kratos:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
networks:
- intranet
volumes:
- type: bind
source: ./kratos
target: /etc/config/kratos
command: -c /etc/config/kratos/kratos.yml migrate sql -e --yes
kratos:
image: oryd/kratos:<version-you-want>
links:
- postgres-kratos:postgres-kratos
environment:
- DSN=postgres://kratos:secret@postgres-kratos:5432/kratos?sslmode=disable&max_conns=20&max_idle_conns=4
ports:
- '4433:4433'
- '4434:4434'
volumes:
- type: bind
source: ./kratos
target: /etc/config/kratos
networks:
- intranet
command: serve -c /etc/config/kratos/kratos.yml --dev --watch-courier
kratos-selfservice-ui-node:
image: oryd/kratos-selfservice-ui-node:latest
environment:
- KRATOS_PUBLIC_URL=http://kratos:4433/
- KRATOS_BROWSER_URL=http://127.0.0.1:4433/
networks:
- intranet
ports:
- "4455:3000"
restart: on-failure
mailslurper:
image: oryd/mailslurper:latest-smtps
ports:
- '4436:4436'
- '4437:4437'
networks:
- intranet
networks:
intranet:
This example uses the following network architecture:
4433
port is the public ("browser") API of Ory Kratos.4434
is the admin API of Ory Kratos.4455
is a port for the user interface implemented by the reference self-service UI.8080
is a port of Ory Oathkeeper.
Other ports and services are available only in the internal network.
Configure Ory Oathkeeper and Ory Kratos
- Create a
kratos
folder and fetch configuration files:
mkdir kratos
wget https://raw.githubusercontent.com/ory/kratos/<version-you-want>/contrib/quickstart/kratos/email-password/identity.schema.json -O kratos/identity.schema.json
wget https://raw.githubusercontent.com/ory/kratos/<version-you-want>/contrib/quickstart/kratos/email-password/kratos.yml -O kratos/kratos.yml
- Create a
oathkeeper
folder andoathkeeper/oathkeeper.yml
with the following content:
import oathkeeper from '!!raw-loader!../../../code-examples/oathkeeper/oathkeeper/oathkeeper.yml'
<CodeBlock language="yaml">{oathkeeper}</CodeBlock>
- Create
oathkeeper/access-rules.yml
with the following content:
import rules from '!!raw-loader!../../../code-examples/oathkeeper/oathkeeper/access-rules.yml'
<CodeBlock language="yaml">{rules}</CodeBlock>
This configuration of Ory Oathkeeper uses the
cookie authenticator against Ory Kratos and proxies only
authenticated requests to http://ws:8080
upstream. The ws
hostname is resolved through the Docker network. If you aren't
deploying your application within Docker, this would just be your localhost IP.
WebSocket service
- Let's create a folder
ws
and create our WebSocket service using Go and Gin framework. Createws/main.go
file with the following content:
import app from '!!raw-loader!../../../code-examples/oathkeeper/ws/main.go'
<CodeBlock language="go">{app}</CodeBlock>
- We need to initialize go modules by running the following commands:
cd ws
go mod init ws
go mod tidy
- Create
ws/index.html
file with the following content:
import index from '!!raw-loader!../../../code-examples/oathkeeper/ws/index.html'
<CodeBlock language="html">{index}</CodeBlock>
- Create
ws/Dockerfile
with the following content:
import dockerfile from '!!raw-loader!../../../code-examples/oathkeeper/ws/Dockerfile'
<CodeBlock language="html">{dockerfile}</CodeBlock>
- We need to add our
ws
service to thedocker-compose.yml
services:
---
ws:
build:
context: "ws"
networks:
- intranet
Testing
- Run
docker-compose up
. - Wait for services to be ready.
- Open
http://127.0.0.1:4455
. - Create a new account.
- Open
http://127.0.0.1:8080
.