Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions facade-poc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Motivation
This set up shows a simple facade implementation with re-authentication.

## Components
* server
* nginx
* client call

# Requirements
* python (tested with version 3.12.2)
* nginx (tested with version 1.25.4)

# Server
1) Create a Virtual Environment for Python

`python3 -m venv venv`

2) Install Flask

`pip3 install flask`

3) Activate the virtual environment for python

`source venv/bin/activate`

4) Create Private Key

`openssl genrsa -aes256 -out server.key 2048`

5) Create Certificate Signing Request

`openssl req -new -key server.key -out server.csr`

6) Create the Certificate

`openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt`

7) Start the server

`python server.py`

8) Test the server

`curl https://127.0.0.1:5000/unsecured --insecure`

9) Test passing an API Key

`curl https://localhost:5000/secured -H "X-API-Key:TEST-API-KEY" --insecure`

# NGINX
Apply the right configuration, found in this repository in `nginx.conf`
On MacOS it is located in `/usr/local/etc/nginx`

## Create Certificates and Adjust NGINX Configuration

1) Create Private Key

`openssl genrsa -aes256 -out server.key 2048`

2) Create Certificate Signing Request

`openssl req -new -key nginx.key -out nginx.csr`

3) Create the Certificate

`openssl x509 -req -days 365 -in nginx.csr -signkey nginx.key -out nginx.crt`

4) Adjust paths in nginx.conf


5) Start nginx

`nginx`

# Start Testing

Test for forbidden on unsecured endpoint

`curl https://localhost/unsecured --insecure`

Test for successful request on secured endpoint with enriched credentials

`curl https://localhost/secured --insecure`

# Troubleshooting

Beware of the nginx state. Sometimes, a reload via `nginx -s reload` is not enough. If it behaves not as expected, try `nginx -s quit` and restart using `nginx`.
73 changes: 73 additions & 0 deletions facade-poc/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@

#user nobody;
worker_processes 1;

error_log /var/log/nginx/error.log;
error_log /var/log/nginx/error.log notice;
error_log /var/log/nginx/error.log info;

#pid logs/nginx.pid;

events {
worker_connections 1024;
}


http {
include mime.types;
default_type application/octet-stream;

#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

#gzip on;

# HTTPS server

server {
listen 443 ssl;
server_name localhost;
ssl_certificate "<ABSOLUTE-PATH-TO-YOUR-PROJECT>/certificates/nginx.crt";
ssl_certificate_key "<ABSOLUTE-PATH-TO-YOUR-PROJECT>/certificates/nginx.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;


location /secured {
# Hardcoded API key
set $api_key "TEST-API-KEY";

# Add the API key as a custom HTTP header
proxy_set_header X-API-Key $api_key;

proxy_pass https://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_ssl_verify off;
}

# Allow access to other locations
location / {
# Define your access permissions here
deny all;
# Additional configurations for other locations if needed
}


}
include servers/*;
}
36 changes: 36 additions & 0 deletions facade-poc/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from flask import Flask, jsonify, request
import ssl

app = Flask(__name__)

# Hardcoded API key
API_KEY = "TEST-API-KEY"
HEADER_NAME = "X-API-Key"

# Unsecured endpoint
@app.route('/unsecured', methods=['GET'])
def unsecured():
data = {'message': 'This is an unsecured endpoint.'}
return jsonify(data)

# Secured endpoint
@app.route('/secured', methods=['GET'])
def endpoint2():
# Check if API key is provided in the request headers
provided_api_key = request.headers.get(HEADER_NAME)

# API key is invalid, return send unauthorized
if provided_api_key != API_KEY:
return jsonify({'error': 'Unauthorized access. Invalid API key.'}), 401


data = {'message': 'This is a secured endpoint.'}
return jsonify(data)

if __name__ == '__main__':
# Generate SSL context
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('certificates/server.crt', 'certificates/server.key') # Provide paths to your certificate and private key files

# Run Flask app with TLS/SSL enabled
app.run(debug=True, ssl_context=context)