Skip to content

lblod/acmidm-login-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ACM/IDM login microservice

Microservice running on mu.semte.ch providing the necessary endpoints to login/logout a user using ACM/IDM as OpenId provider. This backend service works together with @lblod/ember-acmidm-login in the frontend.

Tutorials

Add the login service to a stack

Add the following snippet to your docker-compose.yml to include the login service in your application stack:

login:
  image: lblod/acmidm-login-service
  environment:
      MU_APPLICATION_AUTH_DISCOVERY_URL: "https://authenticatie.vlaanderen.be/op/.well-known/openid-configuration"
      MU_APPLICATION_AUTH_CLIENT_ID: "my-client-id"
      MU_APPLICATION_AUTH_REDIRECT_URI: "https://myapp.vlaanderen.be/authorization/callback"
      MU_APPLICATION_AUTH_CLIENT_SECRET: "my-secret"

Fill in the environment variables with the information you received from ACM/IDM.

Add rules to the dispatcher.ex to dispatch requests to the login service. E.g.

  match "/sessions/*path" do
    Proxy.forward conn, path, "http://login/sessions/"
  end

The host login in the forward URL reflects the name of the login service in the docker-compose.yml file as defined above.

Restart the dispatcher service and create the login service:

docker compose restart dispatcher
docker compose up -d login

How-to guides

Authenticate using client id and secret

To authenticate using a client ID and secret, simply configure the MU_APPLICATION_AUTH_CLIENT_ID and MU_APPLICATION_AUTH_CLIENT_SECRET environments variables on the service:

login:
  image: lblod/acmidm-login-service
  environment:
      MU_APPLICATION_AUTH_CLIENT_ID: "my-client-id"
      MU_APPLICATION_AUTH_CLIENT_SECRET: "my-secret"

Make sure to keep the client secret private (e.g. don't commit it in your code repository). Therefore this environment variable is typcially set in docker-compose.override.yml.

Authenticate using JWT with public/private key

To authenticate using JWT with a public/private key pair, you first need to generate a public and private key.

mu script login generate-jwk

Copy the private key into ./config/openid/jwk_private_key.json. Make sure not to commit this file in your code repository.

Share the public key with the OpenID Connect Provider (for ACM/IDM by filling it in in the integration document). Also store it somewhere in a file as backup.

Next, set the MU_APPLICATION_AUTH_CLIENT_ID environment variable and mount the config folder as a volume in the login service:

login:
  image: lblod/acmidm-login-service
  environment:
      MU_APPLICATION_AUTH_CLIENT_ID: "my-client-id"
  volumes:
    - ./config/openid:/config

Reference

Configuration

The following environment variables must be configured:

  • MU_APPLICATION_AUTH_DISCOVERY_URL [string]: OpenId discovery URL for authentication
  • MU_APPLICATION_AUTH_CLIENT_ID [string]: Client id of the application in ACM/IDM
  • MU_APPLICATION_AUTH_REDIRECT_URI [string]: Redirect URI of the application configured in ACM/IDM

In case of authentication using a client id and secret, the following environment variable must be set:

  • MU_APPLICATION_AUTH_CLIENT_SECRET [string]: Client secret of the application in ACM/IDM

Client ID and client secret typically differ per deployment environment.

In case of authentication using a JWT token with a public/private key, the following environment variable can optionally be set:

  • MU_APPLICATION_AUTH_JWK_PRIVATE_KEY [string]: Path to a JSON file containing the private key to sign the JWT client assertion with. (default: /config/jwk_private_key.json)

The following environment variables can optionally be set to configure the name of the claim from which specific information is retrieved:

  • MU_APPLICATION_AUTH_ROLE_CLAIM [string]: Key of the claim that contains the user's roles (default abb_loketLB_rol_3d)
  • MU_APPLICATION_AUTH_USERID_CLAIM [string]: Key of the claim that contains the user's identifier (default rrn)
  • MU_APPLICATION_AUTH_ACCOUNTID_CLAIM [string]: Key of the claim that contains the account's identifier (default vo_id)
  • MU_APPLICATION_AUTH_GROUPID_CLAIM [string]: Key of the claim that contains the identifier for the user's group (default vo_orgcode)

The following environment variables can optionally be set to configure the graphs and base URIs for the generated data:

  • MU_APPLICATION_RESOURCE_BASE_URI [string]: Base URI to use for resources created by this service. The URI must end with a trailing slash! (default: http://data.lblod.info/)
  • MU_APPLICATION_GRAPH [string]: URI of the graph in which Bestuurseenheden are stored (default http://mu.semte.ch/graphs/public)
  • SESSION_GRAPH [string]: URI of the graph in which sessions are stored (default http://mu.semte.ch/graphs/sessions)
  • ACCOUNT_GRAPH_TEMPLATE [string]: URI template of the graph in which accounts are stored. You can (optionally use) {{groupId}} (default http://mu.semte.ch/graphs/organizations/{{groupId}})
  • USER_GRAPH_TEMPLATE [string]: URI template of the graph in which users are stored. You can (optionally use) {{groupId}} (default http://mu.semte.ch/graphs/organizations/{{groupId}})
  • LOGS_GRAPH [string]: URI of the graph in which LogEntries are stored (default http://mu.semte.ch/graphs/public).

The following environment variables can optionally be set:

  • DEBUG_LOG_TOKENSETS: When set, received tokenSet information is logged to the console.
  • LOG_SINK_URL: When set, received tokenSet information is sent to the configured sink URL.
  • MU_APPLICATION_AUTH_REQUEST_TIMEOUT [int]: Timeout in ms of OpenID HTTP requests (default 5000)

Data model

Prefixes

Prefix URI
adms http://www.w3.org/ns/adms#
foaf http://xmlns.com/foaf/0.1/
skos http://www.w3.org/2004/02/skos/core#
dcterms http://purl.org/dc/terms/
besluit http://data.vlaanderen.be/ns/besluit#
ext http://mu.semte.ch/vocabularies/ext/
acmidm http://mu.semte.ch/vocabularies/ext/acmidm/

User

Class

foaf:Person

Properties
Name Predicate Range Definition
identifier adms:identifier adms:Identifier Unique identifier of the user
firstName foaf:firstName string First name of the user
familyName foaf:familyName string Last name of the user

Identifier

Class

adms:Identifier

Properties
Name Predicate Range Definition
notation skos:notation string Value by which the user can be uniquely identified. Value of the rrn claim by default.

Account

Class

foaf:OnlineAccount

Properties
Name Predicate Range Definition
identifier dcterms:identifier string Value by which the account can be uniquely identified. Value of the vo_id claim by default.
doelgroepcode acmidm:doelgroepCode string Code of the target group as received from ACM/IDM
doelgroepnaam acmidm:doelgroepNaam string Name of the target group as received from ACM/IDM

Group

Class

besluit:Bestuurseenheid

Session

Class

n/a

Properties
Name Predicate Range Definition
account session:account foaf:OnlineAccount Account linked to the authenticated session.
group ext:sessionGroup besluit:Bestuurseenheid Group associated with the authenticated session.
role ext:sessionRole string User roles associated with the authenticated session.

API

POST /sessions

Log the user in by creating a new session, i.e. attaching the user's account to a session.

Before creating a new session, the given authorization code gets exchanged for an access token with an OpenID Provider (ACM/IDM) using the configured discovery URL. The returned access token is decoded to retrieve information to attach to the user, account and the session. If the OpenID Provider returns a valid access token, a new user and account are created if they don't exist yet and a the account is attached to the session.

The service handles the following claims included in the access token. Only the claims configured through the environment variables are required. All other claims are optional.

  • env.MU_APPLICATION_AUTH_USERID_CLAIM1
  • given_name1
  • family_name1
  • env.MU_APPLICATION_AUTH_ACCOUNTID_CLAIM2
  • vo_doelgroepcode2
  • vo_doelgroepnaam2
  • env.MU_APPLICATION_AUTH_GROUPID_CLAIM3
  • env.MU_APPLICATION_AUTH_ROLE_CLAIM3

1Information is attached to the user object in the store

2 Information is attached to the account object in the store

3 Information is attached to the session in the store

Request body
{ authorizationCode: "secret" }
Response
201 Created

On successful login with the newly created session in the response body:

{
  "links": {
    "self": "sessions/current"
  },
  "data": {
    "type": "sessions",
    "id": "b178ba66-206e-4551-b41e-4a46983912c0",
    "attributes": {
        "roles": [
            "LoketLB-mandaatGebruiker"
        ]
    }
  },
  "relationships": {
    "account": {
      "links": {
        "related": "/accounts/f6419af0-c90f-465f-9333-e993c43e6cf2"
      },
      "data": {
        "type": "accounts",
        "id": "f6419af0-c90f-465f-9333-e993c43e6cf2"
      }
    },
    "group": {
      "links": {
        "related": "/bestuurseenheden/f6419af0-c60f-465f-9333-e993c43e6ch5"
      },
      "data": {
        "type": "bestuurseenheden",
        "id": "f6419af0-c60f-465f-9333-e993c43e6ch5"
      }
    }
  }
}
400 Bad Request
  • if session header is missing. The header should be automatically set by the identifier.
  • if the authorization code is missing
401 Bad Request
  • on login failure. I.e. failure to exchange the authorization code for a valid access token with ACM/IDM
403 Bad Request
  • if the session cannot be attached to an exsting group (bestuurseenheid) based on the received organization code from ACM/IDM

DELETE /sessions/current

Log out the current user, i.e. remove the session associated with the current user's account.

Response
204 No Content

On successful logout

400 Bad Request

If session header is missing or invalid. The header should be automatically set by the identifier.

GET /sessions/current

Get the current session

Response
200 Created
{
  "links": {
    "self": "sessions/current"
  },
  "data": {
    "type": "sessions",
    "id": "b178ba66-206e-4551-b41e-4a46983912c0",
    "attributes": {
        "roles": [
            "LoketLB-mandaatGebruiker"
        ]
    }
  },
  "relationships": {
    "account": {
      "links": {
        "related": "/accounts/f6419af0-c90f-465f-9333-e993c43e6cf2"
      },
      "data": {
        "type": "accounts",
        "id": "f6419af0-c90f-465f-9333-e993c43e6cf2"
      }
    },
    "group": {
      "links": {
        "related": "/bestuurseenheden/f6419af0-c60f-465f-9333-e993c43e6ch5"
      },
      "data": {
        "type": "bestuurseenheden",
        "id": "f6419af0-c60f-465f-9333-e993c43e6ch5"
      }
    }
  }
}
400 Bad Request

If session header is missing or invalid. The header should be automatically set by the identifier.

ACM/IDM OpenID Connect

More information on the OpenID Connect integration with ACM/IDM can be found on the ACM/IDM documentation website (Dutch only).

Currently this service supports 2 of the authentication methods (see 'How-to guides')

  1. Authentication using client ID and secret via basic auth
  2. Authentication using a JWT token with an RSA256 public/private key