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.
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
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
.
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
The following environment variables must be configured:
MU_APPLICATION_AUTH_DISCOVERY_URL
[string]: OpenId discovery URL for authenticationMU_APPLICATION_AUTH_CLIENT_ID
[string]: Client id of the application in ACM/IDMMU_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 (defaultabb_loketLB_rol_3d
)MU_APPLICATION_AUTH_USERID_CLAIM
[string]: Key of the claim that contains the user's identifier (defaultrrn
)MU_APPLICATION_AUTH_ACCOUNTID_CLAIM
[string]: Key of the claim that contains the account's identifier (defaultvo_id
)MU_APPLICATION_AUTH_GROUPID_CLAIM
[string]: Key of the claim that contains the identifier for the user's group (defaultvo_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 (defaulthttp://mu.semte.ch/graphs/public
)SESSION_GRAPH
[string]: URI of the graph in which sessions are stored (defaulthttp://mu.semte.ch/graphs/sessions
)ACCOUNT_GRAPH_TEMPLATE
[string]: URI template of the graph in which accounts are stored. You can (optionally use){{groupId}}
(defaulthttp://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}}
(defaulthttp://mu.semte.ch/graphs/organizations/{{groupId}}
)LOGS_GRAPH
[string]: URI of the graph in which LogEntries are stored (defaulthttp://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 (default5000
)
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/ |
foaf:Person
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 |
adms:Identifier
Name | Predicate | Range | Definition |
---|---|---|---|
notation | skos:notation | string | Value by which the user can be uniquely identified. Value of the rrn claim by default. |
foaf:OnlineAccount
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 |
besluit:Bestuurseenheid
n/a
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. |
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_CLAIM
1given_name
1family_name
1env.MU_APPLICATION_AUTH_ACCOUNTID_CLAIM
2vo_doelgroepcode
2vo_doelgroepnaam
2env.MU_APPLICATION_AUTH_GROUPID_CLAIM
3env.MU_APPLICATION_AUTH_ROLE_CLAIM
3
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
{ authorizationCode: "secret" }
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"
}
}
}
}
- if session header is missing. The header should be automatically set by the identifier.
- if the authorization code is missing
- on login failure. I.e. failure to exchange the authorization code for a valid access token with ACM/IDM
- if the session cannot be attached to an exsting group (bestuurseenheid) based on the received organization code from ACM/IDM
Log out the current user, i.e. remove the session associated with the current user's account.
On successful logout
If session header is missing or invalid. The header should be automatically set by the identifier.
Get the current session
{
"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"
}
}
}
}
If session header is missing or invalid. The header should be automatically set by the identifier.
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')
- Authentication using client ID and secret via basic auth
- Authentication using a JWT token with an RSA256 public/private key