Comment implémenter le SSO : Un tutoriel complet
Accélérer l’adoption de votre application B2B. L’authentification Single Sign-On (SSO) permet aux organisations d’authentifier leurs utilisateurs sur des applications tierces avec leur propre solution de gestion d’identité et d’accès. Avec cette intégration, vous embarquez dans votre code une authentification SSO en seulement deux requêtes API.
- Quickstart
- 15 min
Dans ce guide, nous vous accompagnerons depuis la configuration du Single Sign-On jusqu’à l’authentification de votre premier utilisateur.
Avant de commencer
Créez votre compte Cryptr gratuitement maintenant, vous aurez ainsi les 3 éléments requis pour suivre ce guide :
- Clé d’API : Vous obtiendrez un
client_id
et unclient_secret
, Vous pouvez lire notre guide pour apprendre comment vous authentifier avec ces éléments pour utiliser l’API Cryptr - Organization: Vous créerez votre première organisation, qui représente par exemple votre client et qui peut être vous même pour un 1er test. En savoir plus sur l'organisation.
- Redirection: Également appelée
redirect_uri
, c'est l'URL vers laquelle votre utilisateur sera redirigé après la réussite de son authentification.
1. Activer votre une 1ére connexion SSO
Pour activer le SSO Cryptr entre vous et le fournisseur d'identité (IDP) de votre client, vous devez activer la “SSO Connection” sur l’organisation de test précédemment créée à votre arrivée sur votre tableau de bord.
Rendez-vous sur la page dédiée à l'Organisation pour laquelle vous souhaitez activer la Connexion SSO. Vous pouvez sélectionner l’organisation via la barre de navigation latérale du répertoire des utilisateurs à gauche de votre écran.
Afin de lancer le processus de configuration SSO pour l'administrateur informatique de cette organisation, qui est le contact désigné au sein de l'entreprise cliente en charge de la gestion des identités et des accès (comme Microsoft, Okta ou Google), il vous suffit de cliquer dessus sur la partie TRY FOR FREE
du bouton de connexion SSO situé en haut à droite. Ce qui active la partie SSO dans le portail de configuration administrateur de cette organisation.
2. Tester vous même l’expérience de configuration
Si vous n’utilisez pas de gestionnaire d’identité, vous aurez besoin de créer un compte sur une solution de gestion des identités et d’accès tels que ceux que possèdent vos propres clients. Même si vous avez déjà un gestionnaire d’identité, nous vous recommandons de créer un compte Okta gratuit pour pouvoir tester le configurateur SSO Cryptr. Okta est un leader du marché du SSO d’entreprise.
Vous avez besoin d'un SSO entièrement configuré sur un gestionnaire d’identité d’entreprise pour tester l'authentification. Cela signifie que vous devez agir comme votre propre administrateur client et finaliser vous-même la configuration. C'est l'occasion de comprendre l’expérience que vont vivre vos clients. 😎
Ensuite, sur l'écran de l'Organisation de test ciblée dans votre tableau de bord Cryptr, vous devez vous inviter avec votre propre adresse e-mail. Ceci permettra de vous enregistrer en tant qu’administrateur informatique de cette Organisation pour faire la configuration SSO dans votre compte de test Okta ou dans votre propre gestionnaire d’identité. Pour ce faire, il vous suffit de cliquer sur le bouton à côté du nombre d'administrateur en haut de l'écran à droite du nom de l'Organisation.
Vous allez recevoir un lien d’accès par email. Il vous suffit de cliquer pour accéder à l’espace de configuration de SSO de votre Organisation, cet espace est réservé aux administrateurs informatiques de vos clients qui pourront configurer le SSO avec votre application en toute autonomie. Il permet à Cryptr l’échange des informations utiles entre Cryptr et la solution de SSO de vos clients, tels que des identifiants, des clés, des fichiers de configuration et des certificats. Le configurateur SSO Cryptr est un tutoriel interactif qui est régulièrement mis à jour.
À la fin de votre accompagnement, le configurateur vous invitera à valider votre paramétrage. Votre SSO est parfaitement configuré, vous êtes prêt pour intégrer l'authentification SSO Cryptr dans votre application.
3. Authentifier les utilisateurs
Veuillez noter que tant que vous n'avez pas fini de configurer votre SSO, il sera impossible de se connecter en SSO en tant qu'utilisateur final. Vous devez avoir terminé l'étape d'essai de connexion SSO « try login » de votre Onboarding pour que les authentifications soient réalisables.
Il y a 3 étapes pour compléter un processus SSO Challenge pour un utilisateur de final de l' Organization
(tel qu'un employé de votre client).
- Depuis votre BackEnd, vous devez demander un SsoChallenge avec le redirect_uri souhaité, l’endroit sur votre applicatif où vous souhaitez que Cryptr redirige l'utilisateur après l'authentification SSO. Cet appel API est protégé par votre clé d’API Cryptr, vous ne devez jamais la réaliser depuis le code de votre FrontEnd.
- Le SsoChallenge comprend l’URL d'autorisation pour votre FrontEnd, il s’agit de l’URL où sera redirigé l’utilisateur, ce dernier s’authentifie via le fournisseur d'identité SSO de l'organisation. Cette URL est à consommation unique.
- Une fois son authentification SSO réussi, l'utilisateur est redirigé vers le
redirect_uri
, avec un code d'autorisation en query paramscode
, qui vous permet de récupérer les Json Web Tokens finaux (JWT).
Demander un challenge SSO
Pour demander un challenge SSO, vous aurez besoin
- De l'email de l'utilisateur
- Le
redirect_uri
, l’endroit dans votre application (URL) où vous souhaitez que Cryptr redirige l'utilisateur après son authentification SSO
Pour utiliser les stratégies d'authentification de Cryptr, vous devez préalablement préciser les redirections à autoriser “redirect_uri” depuis votre tableau de bord Cryptr. Si vous n'avez pas fourni de redirection dans votre demande de Challenge, la redirection par défaut sera utilisée. Cryptr vous incite lors de la création de votre compte à créer votre première redirection pour votre environnement de développement (sandbox).
Voici un exemple de requête :
- cURL
- Java
- JavaScript
- PHP - Guzzle
- Python
- Ruby
- C#
curl -X POST '${cryptr_service_url}/api/v2/sso-saml-challenge' \
-d user_email="john@misapret.com" \
-d redirect_uri="https//example-of_url.com/welcome-back-user"
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "redirect_uri=https//example-of_url.com/welcome-back-user&user_email=john@misapret.com");
Request request = new Request.Builder()
.url("${cryptr_service_url}/api/v2/sso-saml-challenge")
.method("POST", body)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Authorization", "Bearer ...")
.build();
Response response = client.newCall(request).execute();
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
myHeaders.append("Authorization", "Bearer ...");
const urlencoded = new URLSearchParams();
urlencoded.append("redirect_uri", "https//example-of_url.com/welcome-back-user");
urlencoded.append("user_email", "john@misapret.com");
const requestOptions = {
method: "POST",
headers: myHeaders,
body: urlencoded,
redirect: "follow"
};
fetch("${cryptr_service_url}/api/v2/sso-saml-challenge", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
<?php
$client = new Client();
$headers = [
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => 'Bearer ...'
];
$options = [
'form_params' => [
'redirect_uri' => 'https//example-of_url.com/welcome-back-user',
'user_email' => 'john@misapret.com'
]];
$request = new Request('POST', '${cryptr_service_url}/api/v2/sso-saml-challenge', $headers);
$res = $client->sendAsync($request, $options)->wait();
echo $res->getBody();
import requests
url = "${cryptr_service_url}/api/v2/sso-saml-challenge"
payload = 'redirect_uri=https%2F%2Fexample-of_url.com%2Fwelcome-back-user&user_email=john@misapret.com'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ...'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "net/http"
url = URI("${cryptr_service_url}/api/v2/sso-saml-challenge")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/x-www-form-urlencoded"
request["Authorization"] = "Bearer ..."
request.body = "redirect_uri=https%2F%2Fexample-of_url.com%2Fwelcome-back-user&user_email=john@misapret.com"
response = http.request(request)
puts response.read_body
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "${cryptr_service_url}/api/v2/sso-saml-challenge");
request.Headers.Add("Authorization", "Bearer ...");
var collection = new List<KeyValuePair<string, string>>();
collection.Add(new("redirect_uri", "https//example-of_url.com/welcome-back-user"));
collection.Add(new("user_email", "john@misapret.com"));
var content = new FormUrlEncodedContent(collection);
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
Cette demande vous fournira une autorisation_url
que votre utilisateur doit procéder à son processus d'authentification SSO avant d'être redirigé vers redirect_uri
souhaité.
Vous pouvez également cibler la connexion SSO appropriée à l'aide du domaine de l'organisation.
Demandez le challenge SSO en utilisant le domaine de l'organisation
- cURL
- Java
- JavaScript
- PHP - Guzzle
- Python
- Ruby
- C#
curl -X POST '${cryptr_service_url}/api/v2/sso-saml-challenge' \
-d org_domain="misapret" \
-d redirect_uri="https//example-of_url.com/welcome-back-user"
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "redirect_uri=https//example-of_url.com/welcome-back-user&org_domain=misapret");
Request request = new Request.Builder()
.url("${cryptr_service_url}/api/v2/sso-saml-challenge")
.method("POST", body)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Authorization", "Bearer ...")
.build();
Response response = client.newCall(request).execute();
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
myHeaders.append("Authorization", "Bearer ...");
const urlencoded = new URLSearchParams();
urlencoded.append("redirect_uri", "https//example-of_url.com/welcome-back-user");
urlencoded.append("org_domain", "misapret");
const requestOptions = {
method: "POST",
headers: myHeaders,
body: urlencoded,
redirect: "follow"
};
fetch("${cryptr_service_url}/api/v2/sso-saml-challenge", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
<?php
$client = new Client();
$headers = [
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => 'Bearer ...'
];
$options = [
'form_params' => [
'redirect_uri' => 'https//example-of_url.com/welcome-back-user',
'org_domain' => 'misapret'
]];
$request = new Request('POST', '${cryptr_service_url}/api/v2/sso-saml-challenge', $headers);
$res = $client->sendAsync($request, $options)->wait();
echo $res->getBody();
import requests
url = "${cryptr_service_url}/api/v2/sso-saml-challenge"
payload = 'redirect_uri=https%2F%2Fexample-of_url.com%2Fwelcome-back-user&org_domain=misapret'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ...'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "net/http"
url = URI("${cryptr_service_url}/api/v2/sso-saml-challenge")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/x-www-form-urlencoded"
request["Authorization"] = "Bearer ..."
request.body = "redirect_uri=https%2F%2Fexample-of_url.com%2Fwelcome-back-user&org_domain=misapret"
response = http.request(request)
puts response.read_body
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "${cryptr_service_url}/api/v2/sso-saml-challenge");
request.Headers.Add("Authorization", "Bearer ...");
var collection = new List<KeyValuePair<string, string>>();
collection.Add(new("redirect_uri", "https//example-of_url.com/welcome-back-user"));
collection.Add(new("org_domain", "misapret"));
var content = new FormUrlEncodedContent(collection);
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
Redirection de l’utilisateur vers son challenge
Vous devrez rediriger votre utilisateur vers l’authorizaiton_url, afin qu'il puisse s'authentifier via le fournisseur d'identité de son organisation avant d'être redirigé vers votre propre application (via redirect_uri). Vous pouvez trouver un exemple de “payload” ci-dessous :
{
"__environment__": "sandbox",
"__type__": "SsoChallenge",
"authorization_url": "https//your-cryptr-service-url.com/org/loirama/oauth2/saml?request_id=8d814d02-35d8-48a9-a033-291fd5959a0c",
"expired_at": 1684774623,
"redirect_uri": "https://loirama.com/welcome-back-user",
"request_id": "8d814d02-35d8-48a9-a033-291fd5959a0c",
"sso_connection_id": "loirama_VqiFf3Y5ogaYRbyEyazDWn"
}
Cette authorization_url
n'est valable que pour une courte période. La meilleure pratique consiste donc à rediriger l'utilisateur dès que le défi est généré, ou à générer le challenge uniquement lorsque l'utilisateur est prêt à se connecter.
Obtenir les tokens après le succès de l'authentification
Une fois que l'utilisateur s'est authentifié avec succès via la connexion SSO, il sera redirigé vers le redirect_uri
fourni préalablement. Cryptr fournira à cette occasion un code d’autorisation code
via query params, pour récupérer les tokens finaux : l‘access_token
et de l’id_token
. Ce dernier contient les données utilisateurs transmises par le fournisseur de SSO de votre client lors de l'authentification.
- cURL
- Java
- JavaScript
- PHP - Guzzle
- Python
- Ruby
- C#
# ... your user finishes their SSO authentication,
# In your app, the user is redirected to your service,
# via the "redirect_uri" provided when you created the challenge (or the default one),
# with the query parameter "code" that we need to fetch the tokens.
curl -X POST '${cryptr_service_url}/oauth/token' \
-d code={code} \
-d grant_type="authorization_code"
# if result.success is true, then
## 1. you get the result.access_token,
## 2. and result.id_token, which contains signed user data.
# else
## your user is unauthorized
# end
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "code=your_code&grant_type=authorization_code");
Request request = new Request.Builder()
.url("${cryptr_service_url}/oauth/token")
.method("POST", body)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.build();
Response response = client.newCall(request).execute();
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
const urlencoded = new URLSearchParams();
urlencoded.append("code", "your_code");
urlencoded.append("grant_type", "authorization_code");
const requestOptions = {
method: "POST",
headers: myHeaders,
body: urlencoded,
redirect: "follow"
};
fetch("${cryptr_service_url}/oauth/token", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
<?php
$client = new Client();
$headers = [
'Content-Type' => 'application/x-www-form-urlencoded'
];
$options = [
'form_params' => [
'code' => 'your_code',
'grant_type' => 'authorization_code'
]];
$request = new Request('POST', '${cryptr_service_url}/oauth/token', $headers);
$res = $client->sendAsync($request, $options)->wait();
echo $res->getBody();
import requests
url = "${cryptr_service_url}/oauth/token"
payload = 'code=your_code&grant_type=authorization_code'
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "net/http"
url = URI("${cryptr_service_url}/oauth/token")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/x-www-form-urlencoded"
request.body = "code=your_code&grant_type=authorization_code"
response = http.request(request)
puts response.read_body
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "${cryptr_service_url}/oauth/token");
var collection = new List<KeyValuePair<string, string>>();
collection.Add(new("code", "your_code"));
collection.Add(new("grant_type", "authorization_code"));
var content = new FormUrlEncodedContent(collection);
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
Nous répondrons à cette demande avec les Json Web Token (JWT) de l'utilisateur, un access_token
et un id_token
. Ce dernier contient les éléments d'identité de l'utilisateur trasmis par la solution de gestion des accès et identités de l'organisation (exemple : votre client).
What's next
Pour vérifier les tokens et garantir la confiance dans les données, vous pouvez utiliser notre guide : comment valider un JWT
Vous pouvez également consulter notre référentiel d'API pour réaliser ces actions via Rest API.