|
|
meteor add hotello:accounts-keycloak
|
|
|
|
|
|
exemple de settings:
|
|
|
|
|
|
```json
|
|
|
{
|
|
|
"public": {
|
|
|
"enableKeycloak": true,
|
|
|
"keycloakUrl": "https://auth.appseducation.fr/auth",
|
|
|
"keycloakRealm": "apps",
|
|
|
},
|
|
|
"keycloak": {
|
|
|
"pubkey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvyVtOgah8FjiXmFcnavID9b0lEhCl5k7jISPkPweOQtB1+hRAajcT7Y4v9babrUAXVL7bAb8nRTJVrks3Jl+o/nfZjfLxx7vIE1mMsRGVAqPg88UgyP79fFBvWdPnrIaIweNqlH5r1WoBOVjsoX0rFNijZqQ5llcC/uUYQW35urjGUJIZlHDSOdp34qnrrnohE3714PUuiKHhqFx15MpzmO/KQuIt0lJXuJ3NgAwt1OndksvP03Kkm0ls7IvveF0GiM2dki2xPRAHvv3jC1hLdHm0kGdrn+EndX0xFwBl9kL5zcjILGwm1gyfeJdfzOQrBUf6WL+FpgNseWq5MD+vwIDAQAB",
|
|
|
"client": "sso",
|
|
|
"adminEmails": ["bruno.boiget@ac-dijon.fr"]
|
|
|
},
|
|
|
}
|
|
|
```
|
|
|
|
|
|
// configuration du service keycloak (dans startup server)
|
|
|
|
|
|
```javascript
|
|
|
if (Meteor.settings.keycloak) {
|
|
|
if (Meteor.settings.public.enableKeycloak === true) {
|
|
|
Accounts.config({
|
|
|
forbidClientAccountCreation: true,
|
|
|
});
|
|
|
ServiceConfiguration.configurations.upsert(
|
|
|
{ service: 'keycloak' },
|
|
|
{
|
|
|
$set: {
|
|
|
loginStyle: 'redirect',
|
|
|
serverUrl: Meteor.settings.public.keycloakUrl,
|
|
|
realm: Meteor.settings.public.keycloakRealm,
|
|
|
clientId: Meteor.settings.keycloak.client,
|
|
|
realmPublicKey: Meteor.settings.keycloak.pubkey,
|
|
|
bearerOnly: false,
|
|
|
},
|
|
|
},
|
|
|
);
|
|
|
}
|
|
|
} else {
|
|
|
console.log('No Keycloak configuration. Please invoke meteor with a settings file.');
|
|
|
}
|
|
|
```
|
|
|
|
|
|
// exemple de mise à jour des infos utilisateur au login (à simplifier selon les champs voulus)
|
|
|
|
|
|
```javascript
|
|
|
if (Meteor.settings.public.enableKeycloak === true) {
|
|
|
// server side login hook
|
|
|
Accounts.onLogin((details) => {
|
|
|
if (details.type === 'keycloak') {
|
|
|
// update user informations from keycloak service data
|
|
|
const updateInfos = {
|
|
|
primaryEmail: details.user.services.keycloak.email,
|
|
|
};
|
|
|
if (details.user.services.keycloak.given_name) {
|
|
|
updateInfos.firstName = details.user.services.keycloak.given_name;
|
|
|
}
|
|
|
if (details.user.services.keycloak.family_name) {
|
|
|
updateInfos.lastName = details.user.services.keycloak.family_name;
|
|
|
}
|
|
|
if (
|
|
|
details.user.username === undefined
|
|
|
|| (details.user.username === details.user.primaryEmail
|
|
|
&& details.user.primaryEmail !== details.user.services.keycloak.email)
|
|
|
) {
|
|
|
// use email as username if no username yet or if username was
|
|
|
// email and email has changed on Keycloak
|
|
|
updateInfos.username = details.user.services.keycloak.email;
|
|
|
}
|
|
|
if (details.user.isActive === false) {
|
|
|
// auto activate user based on email address
|
|
|
if (checkDomain(details.user.services.keycloak.email)) {
|
|
|
updateInfos.isActive = true;
|
|
|
updateInfos.isRequest = false;
|
|
|
} else {
|
|
|
// user email not whitelisted, request activation by admin
|
|
|
updateInfos.isRequest = true;
|
|
|
}
|
|
|
}
|
|
|
Meteor.users.update({ _id: details.user._id }, { $set: updateInfos });
|
|
|
// Manage primary email change
|
|
|
if (details.user.primaryEmail !== details.user.services.keycloak.email) {
|
|
|
Accounts.addEmail(details.user._id, details.user.services.keycloak.email, true);
|
|
|
if (details.user.primaryEmail !== undefined) {
|
|
|
Accounts.removeEmail(details.user._id, details.user.primaryEmail);
|
|
|
}
|
|
|
}
|
|
|
// check if user is defined as admin in settings
|
|
|
if (Meteor.settings.keycloak.adminEmails.indexOf(details.user.services.keycloak.email) !== -1) {
|
|
|
if (!Roles.userIsInRole(details.user._id, 'admin')) {
|
|
|
Roles.addUsersToRoles(details.user._id, 'admin');
|
|
|
console.log(i18n.__('api.users.adminGiven'), details.user.services.keycloak.email);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
`
|
|
|
|
|
|
// Dans le formulaire de login
|
|
|
|
|
|
* créer un bouton qui appelle Meteor.loginWithKeycloak() au lieu de Meteor.loginWithPassword({...})
|
|
|
* attention: comme on est redirigé sur le serveur keycloak, il n'est pas possible d'utiliser un callback pour rediriger sur une page après le login.
|
|
|
* Il faut que la page de login soit capable de détecter que l'utilisateur est loggué et redirige sur /home une fois que c'est le cas
|
|
|
|
|
|
|
|
|
// si besoin de déconnecter l'utilisateur de keycloak au logout
|
|
|
|
|
|
* créer une route /logout sur laquelle rediriger après l'appel au logout de keycloak (composant qui fait appel à Meteor.logout())
|
|
|
* pour déconnecter: rediriger sur keycloak
|
|
|
|
|
|
```javascript
|
|
|
const keycloakLogout = () => {
|
|
|
const { keycloakUrl, keycloakRealm } = Meteor.settings.public;
|
|
|
const keycloakLogoutUrl = `${keycloakUrl}/realms/${keycloakRealm}/protocol/openid-connect/logout`;
|
|
|
const redirectUri = `${Meteor.absoluteUrl()}/logout`;
|
|
|
window.location = `${keycloakLogoutUrl}?post_logout_redirect_uri=${redirectUri}`;
|
|
|
};
|
|
|
``` |