Fixes from frontend/backend url separation (#1829)

* Fixes from frontend/backend url separation

This fixes the CORS and CSP headers.

Also, in thie commit, I removed the cors_supports_credentials config parameter,
which was recently introduced.
Instead, the logic determines the need to use CORS headers if the
web_page_url is set.

 #1778
This commit is contained in:
bmccandless
2020-09-12 10:56:31 -07:00
committed by GitHub
parent 4b240920e2
commit 6a7ae8bc8e
5 changed files with 24 additions and 14 deletions
-3
View File
@@ -341,9 +341,6 @@ def handle_api_base_url(app, app_config):
if not api_base_url:
return
if api_base_url.endswith("/"):
api_base_url = api_base_url[:-1]
sha256 = hashlib.sha256(api_base_url.encode()).hexdigest()
script_name = f"api_base_url-{sha256}.js"
script_path = os.path.join(app.root_path, "../common/web/templates", script_name)
+1 -1
View File
@@ -296,7 +296,7 @@ class CliLaunchServer(Server):
"application/octet-stream",
]
Compress(app)
if app_config.server_config.app__cors_supports_credentials or app_config.server_config.app__debug:
if app_config.server_config.app__debug:
CORS(app, supports_credentials=True)
+5 -3
View File
@@ -435,7 +435,6 @@ class ServerConfig(BaseConfig):
self.app__generate_cache_control_headers = dc["app"]["generate_cache_control_headers"]
self.app__server_timing_headers = dc["app"]["server_timing_headers"]
self.app__csp_directives = dc["app"]["csp_directives"]
self.app__cors_supports_credentials = dc["app"]["cors_supports_credentials"]
self.app__api_base_url = dc["app"]["api_base_url"]
self.app__web_base_url = dc["app"]["web_base_url"]
@@ -506,7 +505,6 @@ class ServerConfig(BaseConfig):
self.check_attr("app__flask_secret_key", (type(None), str))
self.check_attr("app__generate_cache_control_headers", bool)
self.check_attr("app__server_timing_headers", bool)
self.check_attr("app__cors_supports_credentials", bool)
self.check_attr("app__csp_directives", (type(None), dict))
self.check_attr("app__api_base_url", (type(None), str))
self.check_attr("app__web_base_url", (type(None), str))
@@ -758,6 +756,8 @@ class ServerConfig(BaseConfig):
def get_api_base_url(self):
if self.app__api_base_url == "local":
return f"http://{self.app__host}:{self.app__port}"
if self.app__api_base_url and self.app__api_base_url.endswith("/"):
return self.app__api_base_url[:-1]
return self.app__api_base_url
def get_web_base_url(self):
@@ -765,7 +765,9 @@ class ServerConfig(BaseConfig):
return f"http://{self.app__host}:{self.app__port}"
if self.app__web_base_url is None:
return self.get_api_base_url()
return self.app__web_base_url
if self.app__web_base_url.endswith("/"):
return self.app__web_base_url[:-1]
return self.api__web_base_url
class DatasetConfig(BaseConfig):
-5
View File
@@ -14,11 +14,6 @@ server:
server_timing_headers: false
csp_directives: null
# CORS: Cross Origin Resource Sharing. If true, this allow users to make
# authenticated requests. This allows cookies and credentials to be submitted
# across domains
cors_supports_credentials: false
# By default, cellxgene will serve api requests from the same base url as the webpage.
# In general api_base_url and web_base_url will not need to be set.
# There are two reasons to set these parameters:
+18 -2
View File
@@ -4,10 +4,11 @@ import sys
import os
import hashlib
import base64
from urllib.parse import urlparse
from flask import json
import logging
from flask_talisman import Talisman
from flask_cors import CORS
from server.common.aws_secret_utils import handle_config_from_secret
from server.common.errors import SecretKeyRetrievalError
@@ -41,6 +42,14 @@ class WSGIServer(Server):
def _before_adding_routes(app, app_config):
script_hashes = WSGIServer.get_csp_hashes(app, app_config)
server_config = app_config.server_config
# add the api_base_url to the connect_src csp header.
extra_connect_src = []
api_base_url = server_config.get_api_base_url()
if api_base_url:
parse_api_base_url = urlparse(api_base_url)
extra_connect_src = [f"{parse_api_base_url.scheme}://{parse_api_base_url.netloc}"]
# This hash should be in sync with the script within
# `client/configuration/webpack/obsoleteHTMLTemplate.html`
@@ -51,7 +60,7 @@ class WSGIServer(Server):
obsolete_browser_script_hash = ["'sha256-/rmgOi/skq9MpiZxPv6lPb1PNSN+Uf4NaUHO/IjyfwM='"]
csp = {
"default-src": ["'self'"],
"connect-src": ["'self'"],
"connect-src": ["'self'"] + extra_connect_src,
"script-src": ["'self'", "'unsafe-eval'"]
+ obsolete_browser_script_hash + script_hashes,
"style-src": ["'self'", "'unsafe-inline'"],
@@ -70,6 +79,13 @@ class WSGIServer(Server):
v = [v]
csp[k] = csp.get(k, []) + v
# Add the web_base_url to the CORS header
web_base_url = server_config.get_web_base_url()
if web_base_url:
web_base_url_parse = urlparse(web_base_url)
allowed_origin = f"{web_base_url_parse.scheme}://{web_base_url_parse.netloc}"
CORS(app, supports_credentials=True, origins=allowed_origin)
Talisman(
app, force_https=server_config.app__force_https, frame_options="DENY", content_security_policy=csp,
)