Sage-Bionetworks / prov-service

lightweight implementation of the Synapse Activity services, based on the PROV spec
3 stars 3 forks source link

HTTPS support for Connexion and Flask #22

Open Pawel-Madej opened 5 years ago

Pawel-Madej commented 5 years ago

When specifying HTTPS as the scheme in the API YAML file, all the URIs in the served Swagger UI are HTTPS endpoints.

The problem: The default server that runs is a “normal” HTTP server. This means that the Swagger UI cannot be used to play with the API. What is the correct way to start a HTTPS server when using Connexion?

One way to solve it (followed by http://flask.pocoo.org/snippets/111/):

from OpenSSL import SSL
context = SSL.Context(SSL.SSLv23_METHOD)
context.use_privatekey_file('yourserver.key')
context.use_certificate_file('yourserver.crt')

app.run(host='127.0.0.1', port='12344',
        debug=False/True, ssl_context=context)

However, Connexion doesn’t provide an ssl_context parameter. This is because Flask doesn’t, either–but it uses **kwargs to send the parameters to the underlying server.

Other options are to use nginx, apache or gunicorn to serve HTTPS.

--- UPDATE --- from version 1.0 (released on April 26th 2018) Flask is supporting HTTPS for run command. More details here: https://github.com/pallets/flask/pull/2606

Pawel-Madej commented 5 years ago

@jaeddy - FYI refers to action item from team meeting:

All communications need to be in SSL (including Provenance)

jaeddy commented 5 years ago

Thanks, @Pawel-Madej. I found this post recently as well, which might be useful. The solution you shared looks a lot simpler though!

tschaffter commented 5 years ago

Here is how the self-signed certificate for the portal is generated:

export CERTS_DIR=certs
mkdir $CERTS_DIR
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
  -subj "/C=US/ST=Washington/L=Seattle/O=Sage Bionetworks/CN=www.sagebionetworks.org" \
  -keyout $CERTS_DIR/server.key -out $CERTS_DIR/server.cert

I decided to use the same certificate for MongoDB (not required). MongoDB requires a pem file which contains both the server key and certificate:

cat $CERTS_DIR/server.key $CERTS_DIR/server.cert > $CERTS_DIR/mongodb.pem
tschaffter commented 5 years ago

It may be that the portal (backend) requires the provenance to run over HTTPS, so we should plan to have this feature enabled. It should also be took complicated to put in place for this python project.

jaeddy commented 5 years ago

Thanks, @tschaffter! This doesn't seem to hard to implement (at least for Python/Flask.. never quite sure what to expect with Neo4j), but I'm probably not the best person to do so. Hopefully someone can take a look at this task, and I'll continue to work on the business logic. :)

lukasz-rakoczy commented 5 years ago

Hi @jaeddy

I've been able to run setup authentication and SSL for neo4j. Please look at the changes in this branch: https://github.com/Sage-Bionetworks/prov-service/tree/neo4j-ssl

To make it running you need to:

/tmp/neo4j
├── certificates
│   ├── revoked
│   ├── server.cert
│   ├── server.key
│   └── trusted
├── conf
│   └── neo4j.conf
├── data
└── logs

I didn't have time to setup the Python side of the communication. This will require to add the generated certificate to the trust store of the Flask server so it trusts the self signed certificate. The SSL secured port will be exposed on the port 7473.