Skip to content

Commit

Permalink
Merge pull request #34 from gematik/add-basic-facade-poc
Browse files Browse the repository at this point in the history
Add a basic facade PoC
  • Loading branch information
MiN0DE authored Apr 2, 2024
2 parents 78e22d1 + 433e8e5 commit 2e64d99
Show file tree
Hide file tree
Showing 3 changed files with 196 additions and 0 deletions.
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)

0 comments on commit 2e64d99

Please sign in to comment.