The Simplifier Server needs a typcial Reverse Proxy as standard setup.
The Reverse Proxy should provide the following services for a secure setup
- SSL-Entladung
- Viren- / Malware-Scans
- Firewall für Webanwendungen
Weitergeleitete Ports:
- 443 (HTTPS)
Anschluss 443
- HTTPS (gültiges Zertifikat)
- moderne, sichere TLS-Konfiguration (inkl. HTTP Strict Transport Security)
- HTTP2, wenn möglich
- Kopfball:
- “Upgrade”: Übergabe vom Client (für WebSockets)
- “X-Real-IP”: IP-Adresse des Clients
- “X-Forwarded-Forwarded-For”: Remote-Adresse des Clients oder X-Forwarded-For-Header des übergeordneten Proxy-Servers.
- “X-Forwarded-Proto”: Originalprotokoll der Anfrage (“http” oder “https”)
- CORS-Header (siehe unten)
- (Vorübergehend) Umleitung von “/” entweder zur AdminUI (“/UserInterface/”) oder zur App Ihrer Wahl (“/appDirect/$appName”)
- Proxy-Verbindung/Lesen/Senden Timeout auf hohen Wert, z. B.
g.
ca. 10 Minuten - Maximale Körpergröße (post, put) auf den entsprechenden Wert, z. B. 20 MB (muss nicht zu groß sein, da Pakete mit 20 MB als einzelne Chunks > übertragen werden)
- Proxy-Weiterleitung an Simplifier AppServer Port 8080 (wenn auf einem anderen Server, muss über die Firewall erreichbar sein)
CORS-Header
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to allow a user agent to access selected resources from a server located on a different origin (domain) than the currently used Web site. A user agent makes a cross-origin HTTP request when requesting a resource from another domain, protocol, or port than the one from which the current document originates.
The CORS mechanism supports secure cross-domain queries and data transfers between browsers and web servers. Modern browsers use CORS in an API container such as XMLHttpRequest or Fetch to minimize the risks of cross-origin HTTP requests.
Für die Anfragemethoden ‘POST’,’ GET’,’ PUT’,’ DELETE’,’PATCH’:
| Name | Header-Wert |
| Zugriffskontrolle-Zulassen-Ursprung | * |
| Zugriffssteuerung-Zulassen-Anmeldeinformationen | STIMMT |
| Zugriffssteuerung-Zulassen-Methoden | ABRUFEN, POSTEN, SETZEN, LÖSCHEN, OPTIONEN, PATCHEN |
| Zugriffssteuerung-Zulassen-Kopfzeilen | DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Authorization, SimplifierToken, SimplifierApp, SimplifierModule, SimplifierModuleInterface, SimplifierClientBusinessObject, SimplifierClientBusinessObjectFunction, sap-cancel-on-close, sap-contextid-accept, MaxDataServiceVersion, DataServiceVersion, Content-Length, SimplifierApiKey, OData-MaxVersion, OData-Version, MIME-Version, X-CSRF-Token |
| Zugriffssteuerung-Expose-Header | remainingTokenLifetime,OData-Version |
Zusätzlich für die Anfragemethode ‘OPTIONS’:
| Name | Header-Wert |
| Zugriffskontrolle-Max-Alter | Artikel-Nr.: 1728000 |
| Name | Code der Antwort |
| Leerer Inhalt | 204, Kein Proxy-Aufruf erforderlich |
Die folgenden Pfade sollten für das Routing zurück an Simplifier konfiguriert werden
| Lage / Pfad | Beschreibung |
| “^/genToken/$” | Der Simplifier Authentification Service auf Basis von Token |
| “^/Vermögenswerte/(.*)$” | Die statischen Assets wie Bilder, PDF-Dateien usw. für eine Anwendung |
| “^/Kunde/(.*)$” | Die Client-REST-API für den Zugriff auf Geschäftsobjekte, Konnektoren oder Plug-ins |
| “^/bibliotheksverwaltet/(.*)$” | Javascript-Bibliotheken von Drittanbietern, die für die HTML5-Anwendungen benötigt werden |
| “^/library-static/(.*)$” | Javascript-Bibliotheken von Drittanbietern, die für die HTML5-Anwendungen benötigt |
| “^/appDirect/(.*)$” | Hosting-Pfad für die erstellten HTML5-Anwendungen |
| “^/Benutzeroberfläche/(.*)$” | Admin Backend Interface Anwendung (sollte nur in einer sicheren Umgebung, internem Netzwerk, zugänglich sein) |
| “^/Authentifizierung/(.*)$” | Externer Authentifizierungsanbieter für z.B. oAuth |
| “^/passwordExpired/(.*)$” | Seite zum Zurücksetzen des Passworts für die Admin-Oberfläche |
| “^/entwickeln/(.*)$” | Plugin-Schnittstelle |
| “^/system-bibliothek/(.*)$” | Systembibliotheken wie OpenUI5 |
| “^/appwizard/(.*)$” | REST-API für App-Assistenten |
| “^/Hybrid/(.*)$” | Launchpad- und Workflow-Integrationswege |
| “^/HybridBenutzerschnittstelle/(.*)$” | Launchpad- und Workflow-Integrationswege |
Um alle obligatorischen Anforderungen zu erfüllen, können Sie das folgende Beispiel einer nginx-Reverse-Proxy-Konfiguration verwenden:
# Run as a less privileged user for security reasons.
user nginx;
worker_processes auto;
events {
worker_connections 1024;
}
pid /var/run/nginx.pid;
http {
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
default upgrade;
'' close;
}
#Redirect to https, using 307 instead of 301 to preserve post data
server {
server_name localhost;
listen 80;
return 307 https://$host$request_uri;
}
server {
listen [::]:443 ssl;
listen 443 ssl http2;
server_name localhost;
# Protect against the BEAST attack by not using SSLv3 at all. If you need to support older browsers (IE6) you may need to add
# SSLv3 to the list of protocols below.
ssl_protocols TLSv1.2;
# Ciphers set to best allow protection from Beast, while providing forwarding secrecy, as defined by Mozilla - https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK;
ssl_prefer_server_ciphers on;
# Optimize TLS/SSL by caching session parameters for 10 minutes. This cuts down on the number of expensive TLS/SSL handshakes.
# The handshake is the most CPU-intensive operation, and by default it is re-negotiated on every new/parallel connection.
# By enabling a cache (of type "shared between all Nginx workers"), we tell the client to re-use the already negotiated state.
# Further optimization can be achieved by raising keepalive_timeout, but that shouldn't be done unless you serve primarily HTTPS.
ssl_session_cache shared:SSL:10m; # a 1mb cache can hold about 4000 sessions, so we can hold 40000 sessions
ssl_session_timeout 24h;
# Use a higher keepalive timeout to reduce the need for repeated handshakes
keepalive_timeout 300; # up from 75 secs default
# remember the certificate for a year and automatically connect to HTTPS
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains';
ssl_certificate /etc/nginx/ssl.crt;
ssl_certificate_key /etc/nginx/ssl.key;
location / {
proxy_pass http://simplifier:8080; # TODO: replace port if app listens on port other than 80
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
client_max_body_size 20m;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,SimplifierToken,SimplifierApp,remainingTokenLifetime';
add_header 'Access-Control-Expose-Headers' 'remainingTokenLifetime,OData-Version';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,SimplifierToken,SimplifierApp,remainingTokenLifetime';
add_header 'Access-Control-Expose-Headers' 'remainingTokenLifetime,OData-Version';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,SimplifierToken,SimplifierApp,remainingTokenLifetime';
add_header 'Access-Control-Expose-Headers' 'remainingTokenLifetime,OData-Version';
}
if ($request_method = 'PUT') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,SimplifierToken,SimplifierApp,remainingTokenLifetime';
add_header 'Access-Control-Expose-Headers' 'remainingTokenLifetime,OData-Version';
}
if ($request_method = 'DELETE') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,SimplifierToken,SimplifierApp,remainingTokenLifetime';
add_header 'Access-Control-Expose-Headers' 'remainingTokenLifetime,OData-Version';
}
if ($request_method = 'PATCH') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS, PATCH';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,SimplifierToken,SimplifierApp,remainingTokenLifetime';
add_header 'Access-Control-Expose-Headers' 'remainingTokenLifetime,OData-Version';
}
location = / {
return 302 https://$host/UserInterface/;
}
}
}
}
In diesem Beispiel wird die
proxy_pass http://simplifier:8080;











