gemini-hlsw / lucuma-sso

Lucuma Single Sign-On Service and Libraries
6 stars 3 forks source link

LUCUMA-SSO

Single sign-on service and support libries for Lucuma.

Server Configuration

SSO requires the following configuration in staging/production.

SSO App Config
Variable Value
LUCUMA_ORCID_CLIENT_ID ORCID Client Id
LUCUMA_ORCID_CLIENT_SECRET ORCID secret
LUCUMA_SSO_COOKIE_DOMAIN Domain for refresh token cookie (gemini.edu)
LUCUMA_SSO_ENVIRONMENT Constant value staging (will go away)
LUCUMA_SSO_HOSTNAME External hostname for this service.
GPG Information

SSO signs JWTs with a private key. Client applications verify JWTs with a public key.

Variable Value
GPG_SSO_PUBLIC_KEY GPG ASCII-armored public key.
GPG_SSO_PRIVATE_KEY GPG ASCII-armored private key.
GPG_SSO_PASSPHRASE Passphrase to read private key.
Heroku Information

The following configuration is provided by Heroku. You must enable the runtime-dyno-metadata extension to get the full set.

Variable
DATABASE_URL
HEROKU_APP_ID
HEROKU_APP_NAME
HEROKU_DYNO_ID
HEROKU_RELEASE_CREATED_AT
HEROKU_RELEASE_VERSION
HEROKU_SLUG_COMMIT
HEROKU_SLUG_DESCRIPTION

Web Client Flow

Initialization

Login

The user must be allowed to choose to log in with ORCID (as a standard user) or log in as a guest. Service users are not interactive users and cannot log in.

Login Roles for Standard Users

Standard users will always be logged in under a PI role. If the user has no such role (possible but unusual) it will be created. The user can later switch to a different role (see Set Role below) and this choice will be peristed in the refresh token. Associating the role with the refresh tokan allows a user to be logged in under several roles at the same time, in different browser sessions.

Guest Login

ORCID Login

Normal Operation

Log Out

Set Role

Back-End Service Workflow

Obtaining a Service JWT

Each back-end service must have its own service JWT for communicating with other services. SsoClient must communicate with SSO to exchange API tokens, so SsoClient users need a service token. You can obtain one by running a one-off Heroku dyno command from your SSO server. The service-name argument is arbitrary but should identify your application for logging purposes (observing-database, facility-service, etc).

heroku run -a <sso-app-name> create-service-user <service-name>

Discussion

It is possible to implement authentication as a middleware, but this makes composition of routes via <+> difficult because the middleware can either (a) reject unauthorized requests with 403 Forbidden, which means no following routes can possibly match; or (b) ignore unauthorized requests, which means the user will see a 404 Not Found instead of 403 Forbidden. So the recommended strategy for now is to check authorization on each route as described above.

Local Development QuickStart

127.0.0.1       localhost local.lucuma.xyz

Use docker-compose to wrangle a dev database. It's way easier than dealing with a real installation.

Command Description
docker-compose up start up the test database
docker-compose up -d start up the test database in the background
docker-compose run postgres psql -h postgres -d lucuma-sso -U jimmy start up a psql shell (password is banana)
docker-compose stop stop the test database
docker-compose down destroy the database

To run locally you need to clean out the default database. If you're just running tests the default db is fine.

psql -h localhost -d postgres -U jimmy -c 'drop database "lucuma-sso"'
psql -h localhost -d postgres -U jimmy -c 'create database "lucuma-sso"'

Docker-compose also starts up a local nginx server that serves an example client application at:

Working on the Schema

The app runs the migrations in /modules/service/src/main/resources/db/migration on startup.

Connecting to the Database

You can connect to youe dev database with locally-installed tools like pgAdmin and psql as follows. Note that it's important to explicitly specify localhost as the host, for example psql -h localhost -d lucuma-sso -U jimmy.

Parameter Value
host localhost
port 5432
database lucuma-sso
user jimmy
password banana

Setting up ORCID Credentials

If you try to run Main you will find that it barfs because it needs some ORCID configuration. To set this up, sign into ORCID as yourself, go to Developer Tools under the name menu and create an API key with redirect URL http://localhost:8080/auth/v1/stage2. This will allow you to test ORCID authentication locally.

You will need to provide GPP_ORCID_CLIENT_ID and GPP_ORCID_CLIENT_SECRET either as environment variables or system properties when you run Main. To do this in VS-Code you can hit F5 and then set up a run configuration as follows after which hitting F5 again should run SSO locally. Output will be in the Debug Console window.

{
  "version": "0.2.0",
  "configurations": [
    {
      "type"       : "scala",
      "request"    : "launch",
      "name"       : "Lucuma SSO",
      "mainClass"  : "lucuma.sso.service.Main",
      "args"       : [],
      "buildTarget": "service",
      "jvmOptions" : [
        "-DLUCUMA_ORCID_CLIENT_ID=<client-id>",
        "-DLUCUMA_ORCID_CLIENT_SECRET=<client-secret>",
      ],
    }
  ]
}