Skip to content

Authentication setup Facebook, Google, ID card, Mobiil ID, Smart ID

tiblu edited this page Dec 5, 2018 · 37 revisions

Facebook

Facebook App configuration

  • Log in to https://developers.facebook.com/
  • Choose "My Apps -> Add New App"
  • Fill the form and click "Create App ID"
  • Pass the "not a robot test"
  • From left side menu select "Settings" (https://developers.facebook.com/apps/YOUR_FACEBOOK_APP_ID/settings/basic/) and fill all thats required in the form. BUT, special notes:
    • "App ID" & "App Secret" - NOTE THOSE DOWN, needed later in CitizenOS configuration
    • "Display name" - make sure it's meaningful. User sees it as "Would you like to share your data with DISPLAY_NAME?"
    • "App domains" - your domain name without protocol ie "citizenos.myorganization.com"
    • "App icon" - users will see this app icon, it's highly recommended that you have a good one that actually reflects your app. Do not leave it empty.
  • Click on the "Products" (+) icon in the left side menu.
  • In the "Add a Product" section choose "Facebook Login" by clicking "Set-up" button
  • Select "Web" to start the setup, of which you just fill the first step:
    • "Site URL" - Your website url which uses the login ie "citizenos.myorganization.com". NOTE: Don't forget to click "Save"
  • Go straight to "Products -> Facebook Login -> Settings" in the left tree (https://developers.facebook.com/apps/YOUR_FACEBOOK_APP_ID/fb-login/settings/)
  • Fill in the "Valid OAuth Redirect URIs" - this needs to point to your instance of CitizenOS API WITH the /api/auth/facebook/callback suffix. For example: https://api.citizenos.myorganization.com/api/auth/facebook/callback.
  • Click "Save changes"
  • From the top-right of the screen click the gray "OFF" toggle to "ON", the "Status" should say "Live".
    • NOTE: If it does not light up green, it will probably let you know what parts of the configuration are missing.

CitizenOS API configuration

  "passport": {
    "facebook": {
      "clientId": "YOUR_FACEBOOK_APP_ID",
      "clientSecret": "YOUR_FACEBOOK_APP_SECRET"
    }
  }
  • Restart the server
  • Test it out

Google

Google OAuth 2.0 credentials setup

  • Log in to https://console.developers.google.com/projectcreate
  • Fill the "Project name" and save.
  • Select your project from the "Select a project" dropdown
  • Click the "-> Go to APIs overview" from the "APIs" section.
  • Click "Credentials" from the left side menu.
  • Click "OAuth consent screen" tab from the right and fill the form.
  • Go to "Credentials" and choose "Create credentials -> OAuth client ID"
  • Choose "Web application" as application type and fill the form:
    • "Name" - name that describes it well. For example "CitizenOS Google Auth PRODUCTION"
    • "Authorized JavaScript origins" - NOT NEEDED, there are no browser requests directly to Google domain, all requests are from CitizenOS API
    • "Authorized redirect URIs" - this needs to point to your instance of CitizenOS API WITH the /api/auth/google/callback suffix. For example: https://api.citizenos.myorganization.com/api/auth/google/callback.
  • Click "Create" and in a popup you should see "Here is your client ID" (ie LOTSOFCHARS.apps.googleusercontent.com) and "Here is your client secret" (ie LOTSOFCHARS). Note those down to add them to CitizenOS API configuration.
  • Enable Google+ API at https://console.developers.google.com/apis/library/plus.googleapis.com by clicking "ENABLE".

CitizenOS API configuration

  • Find your Facebook "Client ID" and "Client secret" that you noted down earlier
  • Update API configuration (local.json):
  "passport": {
    "google": {
      "clientId": "YOUR_GOOGLE_CLIENT_ID",
      "clientSecret": "YOUR_GOOGLE_CLIENT_SECRET"
    }
  }
  • Restart the server
  • Test it out

ID-card

You need:

2 different setups depending if:

  • Your Citizen OS API instance has STATIC PUBLIC IP
  • Your Citizen OS API instance has DYNAMIC PUBLIC IP (cloud)

Your Citizen OS API instance has STATIC PUBLIC IP

You need:

  • Proxy to request client certificate for POST /api/auth/id, which means you have to configure the SK root certificate bundle.
  • Proxy to write the certificate to X-SSL-Client-Cert request header
  • Proxy to pass the request downstream

Example for on Nginx configuration

  • Create the SK ESTEID certificate bundle
wget https://sk.ee/upload/files/EE_Certification_Centre_Root_CA.pem.crt                                      
wget https://sk.ee/upload/files/ESTEID-SK_2011.pem.crt
wget https://sk.ee/upload/files/ESTEID-SK_2015.pem.crt
wget http://c.sk.ee/EE-GovCA2018.pem.crt
wget http://c.sk.ee/esteid2018.pem.crt

cat EE_Certification_Centre_Root_CA.pem.crt ESTEID-SK_2011.pem.crt ESTEID-SK_2015.pem.crt EE-GovCA2018.pem.crt esteid2018.pem.crt > esteid_bundle.crt
  • VERY IMPORTANT - Your main proxy configuration (yourdomain.com) of Citizen OS API should strip X-SSL-CLIENT-CERT header so that session is not created by sending a valid certificate in the header!
server {
    listen 443;
    server_name yourdomain.com;
    ...
    location / {
        proxy_set_header X-SSL-CLIENT-CERT ""
    }
}
  • Nginx configuration to for client certificate
server {
    listen 443;
    server_name id.yourdomain.com;

    ssl on;
    ssl_certificate /your/secure/location/id.yourdomain.com.bundle.crt;
    ssl_certificate_key /your/secure/location/id.yourdomain.com.key;
    ssl_client_certificate /your/secure/location/esteid_bundle.crt; # generated esteid bundle
    ssl_verify_client on;
    ssl_session_cache off;
    ssl_verify_depth 2;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    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:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_prefer_server_ciphers on;

    location /api/auth/id {
            expires -1;

            if ($ssl_client_verify != SUCCESS) { 
                    return 403; 
            }

            proxy_pass http://localhost:3000; # CitizenOS API host and port
            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-SSL-CLIENT-VERIFY $ssl_client_verify;
            proxy_set_header X-SSL-CLIENT-CERT $ssl_client_cert;
    }

    location / {
        return 444;
    }
}

NOTE: To my knowledge Nginx does not support client certificate authentication configuration for single location, thus you need to have different server configuration.

More reading:

Your Citizen OS API instance has DYNAMIC PUBLIC IP (cloud)

You need:

  "services": {
    "idCard": {
      "serviceUrl": "https://id-auth.yourdomain.com:3002/info",
      "apiKey": "ID_AUTH_API_KEY"
    }
  }

Further reading

Mobiil-ID

NOTE: DigiDocService requires a static public IP in production environment, BUT not in testing environment.

Your Citizen OS API instance has STATIC PUBLIC IP

  • Contract with SK to DigiDocService - https://www.sk.ee/en/services/validity-confirmation-services/?service/validity_confirmation. You can use test service without a contract.
  • Citizen OS API configuration:
    • Production
    "services": {
      "digiDoc": {
        "serviceWsdlUrl": "https://digidocservice.sk.ee/?wsdl",
        "serviceName": "YOUR_SERVICE_NAME_IN_CONTRACT"
      }
    },
    
    • Test/development
    "services": {
      "digiDoc": {
        "serviceWsdlUrl": "https://tsp.demo.sk.ee/dds.wsdl",
        "serviceName": "Testimine"
      }
    }
    

Your Citizen OS API instance has DYNAMIC PUBLIC IP (cloud)

Out of luck, you do need static public IP for using DDS services.

server {
    listen 8000;
    server_name ddsproxy.yourdomain.com;

    ssl on;
    ssl_certificate /your/secure/location/ddsproxy.yourdomain.com.bundle.crt;
    ssl_certificate_key /your/secure/location/ddsproxy.yourdomain.com.key;

    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout  5m;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    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:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

    ssl_prefer_server_ciphers on;

    ssl_dhparam /etc/ssl/dhparams.pem;

    location / {
        if ($http_authorization != 'Bearer YOUR_SECRET_TOKEN_DEFINED_IN_PROXY_CONFIG') {
                  return 401;
        }

        proxy_pass https://digidocservice.sk.ee;
        proxy_set_header Authorization ""; #Hide the authroization header from upstream
    }
}
  • Configure Citizen OS API to use it:
  "services": {
    "digiDoc": {
      "serviceWsdlUrl": "https://ddsproxy.yourdomain.com:8000/?wsdl",
      "serviceName": "YOUR_SERVICE_NAME_IN_CONTRACT",
      "token": "YOUR_SECRET_TOKEN_DEFINED_IN_PROXY_CONFIG"
    }
  }

Further reading

Smart-ID

NOTE: DigiDocService requires a static public IP in production environment, BUT not in testing environment.

Your Citizen OS API instance has STATIC PUBLIC IP

  • Contract with SK to DigiDocService - https://www.sk.ee/en/services/validity-confirmation-services/?service/validity_confirmation. Choose "I want to support Smart-ID in my services". You can use test service without a contract.
  • Citizen OS API configuration:
    • Production
    "smartId": {
      "hostname": "rp-api.smart-id.com",
      "apiPath": "/v1",
      "relyingPartyUUID": "YOUR_RELYING_PARTY_UUID",
      "replyingPartyName": "YOUR_RELYING_PARTY_NAME"
    }
    
    • Test/development
    "smartId": {
      "hostname": "sid.demo.sk.ee",
      "apiPath": "/smart-id-rp/v1",
      "relyingPartyUUID": "00000000-0000-0000-0000-000000000000",
      "replyingPartyName": "DEMO"
    }
    

Your Citizen OS API instance has DYNAMIC PUBLIC IP (cloud)

Out of luck, you do need static public IP for using DDS services.

server {
    listen 8001;
    server_name smartidproxy.yourdomain.com;
    
    ssl on;
    ssl_certificate /your/secure/location/smartidproxy.yourdomain.com.bundle.crt;
    ssl_certificate_key /your/secure/location/smartidproxy.yourdomain.com.key;

    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout  5m;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    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:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

    ssl_prefer_server_ciphers on;

    ssl_dhparam /etc/ssl/dhparams.pem;

    location / {
        if ($http_authorization != 'Bearer YOUR_SECRET_TOKEN_DEFINED_IN_PROXY_CONFIG') {
            return 401;
        }

        proxy_pass https://rp-api.smart-id.com;
        #proxy_pass https://sid.demo.sk.ee;
        proxy_http_version 1.1;
        proxy_set_header Authorization ""; #Hide the authroization header from upstream
   }
}
  • Configure Citizen OS API to use it:
"services": {
    "smartId": {
      "hostname": "smartidproxy.yourdomain.com:8001",
      "authorizeToken": "YOUR_SECRET_TOKEN_DEFINED_IN_PROXY_CONFIG",
      "apiPath": "/v1"
    }
}

Further reading