Configuration

Plug-Front

Plug-Front is the frontend component of Plug-SSO, normally running on the same box as the reverse proxy (nginx). Reverse proxy validates all traffic through Plug-Front. Plug-Front communicates with Plug-Back which is the backend component.

Plug-Front retrieves needed configuration from Plug-Back during start-up. For doing that, the only local configuration needed is how to connect to Plug-Back including failover/load-balancing.

Configuration example:

<plug-front>/config/config.yml

plugfront:
  backend:
    baseurls:
    - https://<plug-back-one>:9091
    - https://<plug-back-two>:9091
    - https://<plug-back-three>:9091
    password: password
    username: plugadm
  loglevel: error
  log_to_console: false
  listen: 0.0.0.0
  port: 9090
Config key Description
plugfront.backend.baseurls Contains a list of backend connection urls having automatic failover to the next in the list to reduce downtime. Using multiple Plug-Front servers, we can load balance backend traffic by using different baseurls ordering. Syntax https://<plug-back-hostname>:<port>. Port must correspond with Plug-Back port configuration
plugfront.backend.password Clear text password will become encrypted on start-up and must correspond with password defined at plug-back
plugfront.backend.username Username must corresponding with username defined at plug-back
plugfront.loglevel error, info or debug. Logs to <plug-front>/logs/plug-front.log having file rollover at 10 MB and keeping 10 files
plugfront.log_to_console true or false. When true, logging to console instead of file, and stdout/stderr redirect can be used if needed
plugfront.listen 0.0.0.0 accept traffic from all internal interfaces
plugfront.port Port used. Reverse proxy (nginx) communicates with Plug-Front using this port

Plug-Back

Plug-Back is the backend component of Plug-SSO having following tasks:

  • Configuration hub for Plug-Front. Plug-Front retrieves configuration from Plug-Back during start-up
  • Authorization
  • Authentication when using local login
  • Two Factor
  • User store (two factor, recovery code and mail-address for self-service recovery purpose). User store changes becomes replicated to all peer hosts defined.

Configuration file have following main components:

<plug-back>/config/config.yml

domains:
- domain_name: Domain1
  authentications:
  - endpoint_name: Google
    pre_login:
      background_image: ./static/img/logo-google.png
      display_name: Login with Google
  authz_endpoint_name: AD
  realms:
  - /app1
  - /app2
  use_authz: true
  use_otp: true
  use_pre_login: true
endpoint:
  oauth:
  - config:
      endpoint_name: Google
      ...
  directory:
  - config:
      endpoint_name: AD
      ...
  scimgateway:
    ...
plugback:
  ...
plugfront:
  ...

Endpoint section contains endpoint configuration used for authentication and authorization. There are three types of endpoints: oauth, directory and scimgateway. We can define as many as we want, and they must have a unique endpoint_name. This endpoint_name will then be used in the domain section for referring to the specific endpoint.

Domains contains one or more domain having the main SSO configuration. For each domain we have to configure:

  • One or more authentications using endpoint_name for referring to the actual authentication endpoint. When having several authentications defined, we also need use_pre_login = true, else the first authentication defined will be used without any pre-login dialog.
  • If using authorization (use_authz = true), authz_endpoint_name must be set to a valid endpoint_name defined in the endpoint section
  • realms contains a list of valid url paths that can be accessed, and any sub paths will automatically be included. Accessing a url having a path not defined in realms will be denied.
  • use_authz = true, activates authorization
  • use_otp = true, enables two factor authentication
  • use_pre_login = true, enables prelogin dialog for selecting where to login. Dialog box will be built dynamically based on what is defined the authentication section and will show background_image and display_name for each option.

Having several domains is useful when we need different types of configuration. For example we have an admin url that only administrators are allowed to access. We could then define a new domain having a realm that includes this url and specify a new authz_endpoint_name that is configured for only allowing administrators e.g. only allowing users having AD group membership = xxx.

Notes regarding domains:

  • There are no Single-Sign On between domains. Accessing a realm (url) in Domain1 and then accessing a realm in Domain2, requires a new authentication/authorization for Domain2.
  • A realm belongs to one domain. This means, we can’t define the same realm (or sub-paths) in other domains
  • realm path will automatically include sub-paths e.g.:
    • /app3/abc also includes all sub-paths below “abc” like /app3/abc/123
    • / includes everything and will override all other realms defined

plugback section contains misc. Plug-Back related configuration
plugfront section contains misc. Plug-Front related configuration

Configuration example 1

  • One domain
  • Direct Azure tenant login (no prelogin dialog box for selecting where to login)
  • No authorization
  • Using two factor
  • Having three plug-back servers (two peers defined)
domains:
- authentications:
  - endpoint_name: AzureMyCompany
  authz_endpoint_name:
  domain_name: Domain1
  realms:
  - /app1
  - /app2
  use_authz: false
  use_otp: true
  use_pre_login: false
endpoint:
  oauth:
  - config:
      endpoint_name: AzureMyCompany
      callback_url: https://<mycompany.com>/plug/auth
      client_id: azure-application-client-id
      client_secret: azure-application-client-secret
      provider: azure
      tenant: AzureAdMyOrg
plugback:
  certificate:
    certfile: plug-back.cert
    keyfile: plug-back.key
  dbsync:
    hostname_peers:
    - plug-back-two.mycompany.com
    - plug-back-three.mycompany.com
    port: 9099
  listen: 0.0.0.0
  log_to_console: false
  loglevel: error
  password: password
  port: 9091
  username: plugadm
plugfront:
  allowlist_domains:
  allowlist_geo_locations:
  allowlist_users:
  cookie:
    httponly: true
    maxage: 0
    samesite_mode: none
    secure: true
  displayname: PlugSSO
  headers:
  jwt:
    maxage: 240
  log_to_console: false
  loglevel: error
  oidc_provider:
  smtp:
    host: smtp.mycompany.com
    proxy:
    password: password
    port: 587
    username: [email protected]

Configuration example 2

Same as example 1, but includes:

  • using prelogin: Azure, Google and local login
  • using built-in directory authorization (not through SCIM Gateway). Checking that user exist in Active Directory as a normal account, is enabled and password not expired
  • claims attributes will become header variables included in the destination communication.
domains:
- authentications:
  - endpoint_name: AzureMyCompany
    pre_login:
      background_image: ./static/img/logo-mycompany.png
      display_name: Login with MyCompany
      url_path: /app1
  - endpoint_name: Google
    pre_login:
      background_image: ./static/img/logo-google.png
      display_name: Login with Google
      url_path: /app1
  - endpoint_name: AD
    pre_login:
      url_path: /app2
  authz_endpoint_name: AD
  domain_name: Domain1
  realms:
  - /app1
  - /app2
  use_authz: true
  use_otp: true
  use_pre_login: true
endpoint:
  oauth:
  - config:
      endpoint_name: AzureMyCompany
      callback_url: https://<mycompany.com>/plug/auth
      client_id: azure-application-client-id
      client_secret: azure-application-client-secret
      provider: azure
      tenant: AzureAdMyOrg
  - config:
      endpoint_name: Google
      auth_url: https://accounts.google.com/o/oauth2/auth
      callback_url: https://<mycompany.com>/plug/auth
      client_id: google-client-id
      client_secret: google-client-secret
      preferreddomain: gmail.com
      provider: google
  directory:
  - config:
      endpoint_name: AD
      base_dn: CN=Users,DC=mycompany,DC=com
      mail_attr: mail
      search_filter: (&(objectClass=person)(|(sAMAccountName={username})(mail={username}))(|(useraccountcontrol=512)(useraccountcontrol=66048)))
      urls:
      - ldaps://<ad-domain-controller-one>:636
      - ldaps://<ad-domain-controller-two>:636
      user_dn: CN=plugsso,CN=Users,DC=mycompany,DC=com
      user_password: password
plugback:
  certificate:
    certfile: plug-back.cert
    keyfile: plug-back.key
  dbsync:
    hostname_peers:
    - plug-back-two.mycompany.com
    - plug-back-three.mycompany.com
    port: 9099
  listen: 0.0.0.0
  log_to_console: false
  loglevel: error
  password: password
  port: 9091
  username: plugadm
plugfront:
  allowlist_domains:
  allowlist_geo_locations:
  allowlist_users:
  cookie:
    httponly: true
    maxage: 0
    samesite_mode: none
    secure: true
  displayname: PlugSSO
  headers:
    claims:
    - sAMAccountName
    - given_name
  jwt:
    maxage: 240
  log_to_console: false
  loglevel: error
  oidc_provider:
  smtp:
    host: smtp.mycompany.com
    proxy:
    password: password
    port: 587
    username: [email protected]

Configuration example 3

Same as example 2, but includes:

  • Two domains
  • Domain2 using same Azure tenant login as Domain1, and includes local login through SCIM Gateway
  • Domain2 using Authorization through SCIM Gateway
domains:
- authentications:
  - endpoint_name: AzureMyCompany
    pre_login:
      background_image: ./static/img/logo-mycompany.png
      display_name: Login with MyCompany
      url_path: /sso/app1
  - endpoint_name: Google
    pre_login:
      background_image: ./static/img/logo-google.png
      display_name: Login with Google
      url_path: /sso/app1
  - endpoint_name: AD
    pre_login:
      url_path: /sso/app2
  authz_endpoint_name: AD
  domain_name: Domain1
  realms:
  - /app1
  - /app2
  use_authz: true
  use_otp: true
  use_pre_login: true
- authentications:
  - endpoint_name: AzureMyCompany
    pre_login:
      background_image: ./static/img/logo-mycompany.png
      display_name: Login with MyCompany
      url_path: /app3
  - endpoint_name: plug-scimgateway
    pre_login:
      display_name: Internal login
      url_path: /app3
  authz_endpoint_name: plug-scimgateway
  domain_name: Domain2
  realms:
  - /app3
  - /app4
  use_authz: true
  use_otp: true
  use_pre_login: true
endpoint:
  oauth:
  - config:
      endpoint_name: AzureMyCompany
      callback_url: https://<mycompany.com>/plug/auth
      client_id: azure-application-client-id
      client_secret: azure-application-client-secret
      provider: azure
      tenant: AzureAdMyOrg
  - config:
      endpoint_name: Google
      auth_url: https://accounts.google.com/o/oauth2/auth
      callback_url: https://<mycompany.com>/plug/auth
      client_id: google-client-id
      client_secret: google-client-secret
      preferreddomain: gmail.com
      provider: google
  directory:
  - config:
      endpoint_name: AD
      base_dn: CN=Users,DC=mycompany,DC=com
      mail_attr: mail
      search_filter: (&(objectClass=person)(|(sAMAccountName={username})(mail={username}))(|(useraccountcontrol=512)(useraccountcontrol=66048)))
      urls:
      - ldaps://<ad-domain-controller-one>:636
      - ldaps://<ad-domain-controller-two>:636
      user_dn: CN=plugsso,CN=Users,DC=mycompany,DC=com
      user_password: password
  scimgateway:
  - config:
      endpoint_name: plug-scimgateway
      method: post
      password: password
      path: /plugsso/api
      urls:
      - http://<scimgateway-host1>:8890
      - http://<scimgateway-host2>:8890
      user: gwadmin
plugback:
  certificate:
    certfile: plug-back.cert
    keyfile: plug-back.key
  dbsync:
    hostname_peers:
    - plug-back-two.mycompany.com
    - plug-back-three.mycompany.com
    port: 9099
  listen: 0.0.0.0
  log_to_console: false
  loglevel: error
  password: password
  port: 9091
  username: plugadm
plugfront:
  allowlist_domains:
  allowlist_geo_locations:
  allowlist_users:
  cookie:
    httponly: true
    maxage: 0
    samesite_mode: none
    secure: true
  displayname: PlugSSO
  headers:
    claims:
    - sAMAccountName
    - given_name
  jwt:
    maxage: 240
  log_to_console: false
  loglevel: error
  oidc_provider:
  smtp:
    host: smtp.mycompany.com
    proxy:
    password: password
    port: 587
    username: [email protected]

Configuration example 4

Example showing the use of built-in OpenID Connect provider:

  • One domain
  • General Oauth OIDC login (previous examples showed simplified Azure and Google)
  • Local login using SCIM Gateway
  • Authorization through SCIM Gateway
  • Using two factor
  • Having three plug-back servers (two peers defined)
  • Built-in OpenID Provider, see section oidc_provider. Also note that we need the callback url that is used by the remote client to be included in the realm definition. This is to allow PlugSSO authentication if not already authenticated.
domains:
- authentications:
  - endpoint_name: SomeOidcProvider
    pre_login:
      background_image: ./static/img/logo-mycompany.png
      display_name: Login with MyCompany
      url_path: /app1
  - endpoint_name: plug-scimgateway
    pre_login:
      display_name: Internal login
      url_path: /app1
  authz_endpoint_name: plug-scimgateway
  domain_name: Domain1
  realms:
  - /app1
  - /app2
  - /auth/system1/callback
  - /auth/system2/callback
  use_authz: true
  use_otp: true
  use_pre_login: true
endpoint:
  oauth:
  - config:
      endpoint_name: SomeOidcProvider
      provider: oidc
      auth_url: https://<host/oauth2/v1/authorize>.
      callback_url: https://<plug-front-hostname>/plug/auth
      client_id: <client-id>.
      client_secret: <client-secret>.
      scopes:
      - openid
      - email
      - profile
      token_url: https://<host/oauth2/v1/token>.
      user_info_url: https://<host/oauth2/v1/userinfo>.
  scimgateway:
  - config:
      endpoint_name: plug-scimgateway
      method: post
      password: password
      path: /plugsso/api
      urls:
      - http://<scimgateway-host1>:8890
      - http://<scimgateway-host2>:8890
      user: gwadmin
plugback:
  certificate:
    certfile: plug-back.cert
    keyfile: plug-back.key
  dbsync:
    hostname_peers:
    - plug-back-two.mycompany.com
    - plug-back-three.mycompany.com
    port: 9099
  listen: 0.0.0.0
  log_to_console: false
  loglevel: error
  password: password
  port: 9091
  username: plugadm
plugfront:
  allowlist_domains:
  allowlist_geo_locations:
  allowlist_users:
  cookie:
    httponly: true
    maxage: 0
    samesite_mode: none
    secure: true
  displayname: PlugSSO
  headers:
    claims:
    - scim_groups
  jwt:
    maxage: 240
  log_to_console: false
  loglevel: error
  oidc_provider:
    issuer: https://<mycompany.com>/plug/oauth
    oidc_configs:
    - callback_url: https://<company1.com/auth/system1/callback>.
      client_id: this_is_client_id1
      client_secret: this_is_client_secret1
    - callback_url: https://<company2.com/auth/system2/callback>.
      client_id: this_is_client_id2
      client_secret: this_is_client_secret2
    signing_certificate:
      certfile: ecdsa.cert
      keyfile: ecdsa.key
  smtp:
    host: smtp.mycompany.com
    proxy:
    password: password
    port: 587
    username: [email protected]
Config key Description
domains contains one or more domain having the main SSO configuration
domains.domain_name uniqe name of the domain
domains.authentications contains one or more authentication options to be used
domains.authentications.endpoint_name referres to the endpoint_name defined in endpoint section that will be used by the authentication process
domains.authentications.pre_login pre-login dialog box configuration
domains.authentications.pre_login.background_image image file to be displayed
domains.authentications.pre_login.display_name name to be displayed with the image file
domains.authentications.pre_login.url_path where to send user after successful login (must be a valid realm in current domain)
domains.authz_endpoint_name referres to the endpoint_name defined in endpoint section that will be used by the authorization process
domains.realms realms contains a list of valid url paths that can be accessed, also automatically including sub paths. Accessing a url having a path not defined in realms will be denied
domains.use_authz true or false. true, activates authorization
domains.use_otp true or false. true, enables two factor authentication
domains.use_pre_login true or false. true, enables prelogin dialog for selecting where to login. Dialog box will be built dynamically based on what is defined in the authentication section and will show background_image and display_name for each option
endpoint contains needed endpoint configuration used for authentication and authorization. There are three types of endpoints: oauth, directory and scimgateway. We can define as many as we want, and they must have a unique endpoint_name. This endpoint_name will then be used in the domain section for referring to a specific endpoint
endpoint.oauth contains one or more oauth endpoint configuration
endpoint.oauth.config configuration section
endpoint.oauth.config.provider azure, google or oidc. oidc is the general OpenID Connect configuration while azure and google are built-in having simplified configuration
endpoint.oauth.config.xxx for oidc, azure and google provider configuration details see xxx
endpoint.directory contains one or more directory endpoint configuration
endpoint.directory.config configuration section
endpoint.directory.config.endpoint_name unique endpoint name
endpoint.directory.config.base_dn where to start ldap search
endpoint.directory.config.mail_attr attribute containing users mail address. If no mail-address and using directory for authentication, user will be forced to enter a mail-address during the OTP registration process (because of self-service recovery code)
endpoint.directory.config.search_filter search filter that should return one user only. If using authorization, filter should also include needed authorization logic. PlugSSO will replace {username} with user login name, normally this would be mail-address or it could be UserId when using local login
endpoint.directory.config.urls one or more ldap/ldaps connection urls. When more than one is defined, there will be failover logic in the sequence defined.
endpoint.directory.config.user_dn user dn having directory read access to all users
endpoint.directory.config.user_password directory user password. Clear text password that will become encrypted on start-up
endpoint.scimgateway contains one or more scimgateway endpoint configuration
endpoint.scimgateway.config configuartion section
endpoint.scimgateway.config.endpoint_name unique endpoint name
endpoint.scimgateway.config.method get or post. Must correspond with custom SCIM Gateway plugin. Plug SSO will always send a body containing known user attributes. If password attribute is included, it means plugin also have to authenticate user including any authorization
endpoint.scimgateway.config.path SCIM Gateway path. Must correspond with custom SCIM Gateway plugin
endpoint.scimgateway.config.urls SCIM Gateway base url. When more than one is defined, there will be failover logic in the sequence defined
endpoint.scimgateway.config.user SCIM Gateway admin user
endpoint.scimgateway.config.password SCIM Gateway admin user password. Clear text password will become encrypted on start-up
plugback backend configuration: plug-back (current server)
plugback.certificate certificate configuration for tls communication
plugback.certificate.certfile certificate file name. File must be located in <plug-back/config/certs
plugback.certificate.keyfile certificate private key file name. File must be located in <plug-back/config/certs
plugback.dbsync changes in local user store database will be synchronized to all other plug-back servers (peers) defined. If we have more than one plug-back server, this section needs to be configured
plugback.dbsync.hostname_peers a list of peer sync hosts (FQDN of the other plug-back servers - current plug-back server should not be include in this list)
plugback.dbsync.port port number used by peer sync
plugback.listen listen port, Plug-Front communicates with Plug-Back using this port
plugback.log_to_console true or false. true or false. When true, logging to console instead of file, and we can use stdout/stderr redirect if needed
plugback.loglevel error, info or debug. Logs to <plug-back>/logs/plug-front.log having file rollover at 10 MB and keeping 10 files
plugback.password clear text password will become encrypted
plugback.port port used
plugback.username user name
plugfront frontend configuration: Plug-Front
plugfront.allowlistdomains one or more mail-domains. If defined, users having mail-address with a domain that is not included in this list will be denied access e.g: MyCompany.com will only allow access to users having mail address <user>@MyCompany.com
plugfront.allowlist_geo_locations one or more two-letter country codes. If defined, clients having ip-address that do not correspond to defined country code will be denied access. Use country code PRIVATE to include 127.0.0.1 and none public ip-addresses. Country code for Norway NO must be double quoted "NO" because yaml evaluate no to false. Also note that nginx needs following configuration for including client ip-address in the PlugSSO communication: proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;. This product includes GeoLite2 data created by MaxMind, available from https://www.maxmind.com. Geolocation database file must be located at Plug-Back config/geolocation/geo.mmdb. This file is a copy of GeoLite2-Country.mmdb. Using GeoIP2 provides a higher-level api
plugfront.allowlistusers one or more login names. If defined, users having login name not defined in this list will be denied access e.g. [email protected] will only allow access to peter
plugfront.cookie cookie configuration
plugfront.cookie.httponly true or false, default true
plugfront.cookie.maxage number of minutes until cookie expires. Default 0 to delete the cookie when the browser is closed
plugfront.cookie.samesite_mode none, lax or strict, default none
plugfront.cookie.secure true or false, default false
plugfront.displayname product name shown in all user dialogs
plugfront.headers header configuration
plugfront.headers.claims comma separated list of claims attributes that will be assigned values if they are included by OAuth or local authentication/authorization. Nginx then having rules for including these claims attributes as header variables
plugfront.jwt JSON webtoken containing user information attached to cookie
plugfront.jwt.maxage number of minutes until jwt expires. User have to re-authenticate when expired. Should be less than cookie.maxage (if cookie.maxage > 0)
plugfront.log_to_console true or false. When true, logging to console instead of file, and stdout/stderr redirect can then be used
plugfront.loglevel error, info or debug. Logs to <plug-front>/logs/plug-front.log having file rollover at 10 MB and keeping 10 files
plugfront.oidc_provider OpenID Connect provider configuration
plugfront.oidc_provider.issuer https://<mycompany.com>/plug/oauth, <mycompay.com> must be routed to Plug-Front
plugfront.oidc_provider.oidc_configs one or more client configuration
plugfront.oidc_provider.oidc_configs.callback_url client callback url. This url must also be included as a realm
plugfront.oidc_provider.oidc_configs.client_id self defined client id
plugfront.oidc_provider.oidc_configs.client_secret self defined client secret
plugfront.oidc_provider.signing_certificate ES256 or RS256 signing certificate
plugfront.oidc_provider.signing_certificate.certfile certificate file name. File must be located in <plug-front/config/certs
plugfront.oidc_provider.signing_certificate.keyfile certificate private key file name. File must be located in <plug-front/config/certs
plugfront.smtp mail configuaration. Mail is used for mail address verification and self-service otp reset code
plugfront.smtp.host mail server e.g. “smtp.office365.com”
plugfront.smtp.proxy if using mailproxy e.g. “http://proxy-host:1234”. Proxy user/password set to same as smtp.user/password
plugfront.smtp.password clear text password will become encrypted
plugfront.smtp.port port used by mailserver e.g. 587, 25 or 465
plugfront.smtp.username mail account for authentication and also the sender of the email, e.g. “[email protected]

General OIDC example (provider=oidc):

oauth:
- config:
  endpoint_name: SomeOidcProvider
  provider: oidc
  auth_url: https://<host/oauth2/v1/authorize>.
  callback_url: https://<mycompany.com>/plug/auth
  client_id: <client-id>.
  client_secret: <client-secret>.
  scopes:
  - openid
  - email
  - profile
  token_url: https://<host/oauth2/v1/token>.
  user_info_url: https://<host/oauth2/v1/userinfo>.
Config key Description
endpoint.oauth.config.endpoint_name unique endpoint name
endpoint.oauth.config.provider oidc, when using general OIDC configuration
endpoint.oauth.config.auth_url external provider authentication url
endpoint.oauth.config.callback_url Plug-Front callbak url, should be: https://<mycompany.com>/plug/auth
endpoint.oauth.config.client_id external provider client id
endpoint.oauth.config.client_secret external provider client secret
endpoint.oauth.config.scopes openid, email, profile
endpoint.oauth.config.token_url external provider token url
endpoint.oauth.config.user_info_url external provider userinfo url

Azure example (provider=azure):

oauth:
- config:
  callback_url: https://<mycompany.com>/plug/auth
  client_id: <azure-client-id>.
  client_secret: <azure-client-secret>.
  endpoint_name: Microsoft
  provider: azure
  tenant: AzureAdMyOrg
Config key Description
endpoint.oauth.config.provider azure, when using Azure
endpoint.oauth.config.tenant AzureAdMyOrg, AzureAdMultipleOrgs or AzureAdAndPersonalMicrosoftAccount. Note, this definition must correspond with your Azure account configuration. AzureADMyOrg: Only accounts in the organizational directory where the app is registered (single-tenant, your company). AzureADMultipleOrgs: Accounts in any organizational directory (multi-tenant, all companies in Microsoft Azure). AzureADandPersonalMicrosoftAccount: Accounts in any organizational directory (multi-tenant) and personal Microsoft accounts (@outlook.com, @hotmail.com, @live.com)

Google example (provider=google):

- config:
  auth_url: https://accounts.google.com/o/oauth2/auth
  callback_url: https://<mycompany.com>/plug/auth
  client_id: <google-client-id>.
  client_secret: <google-client-secret>.
  endpoint_name: Google
  preferreddomain: gmail.com
  provider: google
Config key Description
endpoint.oauth.config.preferreddomain domain suffix to be added automatically by Google provided login dialog
endpoint.oauth.config.provider google, when using Google

Nginx

Nginx must be configured to validate all requests through PlugSSO. Any claim headers returned by PlugSSO can also be included as headers to the final forwarded destination.

Configuration must include the "Mandatory Start/End section" shown in example below. In addition, each proxy location section must include the PlugSSO authentication at the very beginning: auth_request /plug/validate;

Nginx configuration example:

worker_processes  1;
error_log  logs/error.log;

events {
  worker_connections  1024;
}

http {
  include mime.types;
  default_type application/octet-stream;
  sendfile on;
  keepalive_timeout 65;
  server_tokens off;

  server {
    # redirect to 443 https
    listen 80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
  }	
	
 server {
    listen 443 ssl;
    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    # current directory is <nginx-path>/conf
    ssl_certificate cert/server.cert;
    ssl_certificate_key cert/server.key;
	
    server_name _;
    root /var/www/html/;	

    proxy_buffer_size          128k;
    proxy_buffers              4 256k;
    proxy_busy_buffers_size    256k;

    # === Mandatory START ===
	
    location = /plug/validate {
      # PlugSSO validation of request (returns 401 or 200)
      proxy_pass http://127.0.0.1:9090/validate?url=$scheme://$http_host$request_uri;
      proxy_set_header Host $http_host;
      proxy_pass_request_body off;
      proxy_set_header Content-Length ""; 	  
    }

    # if validate returns `401 not authorized`, forward request to the error401 block for login
    error_page 401 = @error401;
	
    location @error401 {
      return 302 $scheme://$http_host/plug/login?url=$scheme://$http_host$request_uri;
    }
	
    location /plug {
      rewrite ^/plug/(.*) /$1 break;
      proxy_pass http://127.0.0.1:9090;
      proxy_set_header Host $http_host;
      # if using geolocation
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # === Mandatory END ===

	
    location /sso {
      # PlugSSO authentication/authorization before forward to destination
      auth_request /plug/validate;
      
      # forward to local static webserver for testing purposes
      rewrite ^/sso/(.*) /$1 break;
      proxy_pass http://127.0.0.1:8899;
	  
	  
      # Example adding sm_user header based on uid claim returned by PlugSSO
      # "error_log logs/error.log debug;" will list X_Plug_Claims_<PlugSSO claim attribute> in the debug log
      auth_request_set $sm_user $upstream_http_X_Plug_Claims_Uid;
      proxy_set_header sm_user $sm_user;
    }

  }
  
 
  server {
    # testing purpose
    listen 8899;
    server_name _;
    root /var/www/html/;

    # return a message for all locations
    add_header Content-Type text/plain;
    return 200 "Yes, you are authorized for: $request_uri";
  }

 
}

Azure

Azure configuration portal: https://portal.azure.com

  • Azure Active Directory - App registrations - New registration
  • Name = PlugSSO, Account types = Single tenant (same as AzureAdMyOrg), Redirect URI = https://<mycompany.com>/plug/auth
  • Branding: Microsoft logon dialog box may have a logo. Logo can be added by uploading a file containing the logo
  • Authentication: Redirect URIs and account types can be changed
  • API permissions: Microsoft Graph - openid (Type = Delegated, Description = Sign users in)
  • Certificates & secrets: Create a “New client secret”. This secret must be defined in Plug-Back configuration file together with the application id that can be found in “Overview”

Note, account types can also be defined by editing the manifest file having one of following:
“signInAudience”: “AzureAdMyOrg”
“signInAudience”: “AzureAdMultipleOrgs”
“signInAudience”: “AzureADandPersonalMicrosoftAccount”

Last modified July 5, 2020