1. Protocole http sans état
L'application Web adopte une architecture navigateur/serveur et http est utilisé comme protocole de communication. HTTP est un protocole sans état. Chaque requête du navigateur sera traitée indépendamment par le serveur et ne sera pas associée aux requêtes précédentes ou ultérieures. Ce processus est illustré dans la figure ci-dessous. Il n'y a pas de connexion entre les trois paires requête/réponse <.>
Mais cela signifie également que tout utilisateur peut accéder aux ressources du serveur via un navigateur. Si vous souhaitez protéger certaines ressources sur le serveur, vous devez limiter les requêtes du navigateur ; , vous devez identifier les demandes du navigateur, répondre aux demandes légitimes et ignorer les demandes illégales ; pour identifier les demandes du navigateur, vous devez connaître l'état de la demande du navigateur. Puisque le protocole http est sans état, laissez le serveur et le navigateur maintenir conjointement un état ! Il s'agit du mécanisme de session
2. Mécanisme de session
La première fois que le navigateur demande au serveur, le serveur crée une session et envoie l'identifiant de session au navigateur dans le cadre de la réponse, et le navigateur stocke l'ID de session et apporte l'ID de session dans les deuxième et troisième requêtes suivantes. Le serveur saura s'il s'agit du même utilisateur en obtenant l'ID de session dans la requête. Ce processus est illustré dans la figure ci-dessous. la même chose que la première requête. Une association est générée
Le serveur enregistre l'objet de session en mémoire Comment le navigateur enregistre-t-il l'identifiant de session ? Vous pouvez penser à deux façons
- Paramètres de demande
- cookie
Utiliser l'identifiant de session comme Pour chaque paramètre de requête, lorsque le serveur reçoit la requête, il peut naturellement analyser les paramètres pour obtenir l'ID de session, et l'utiliser pour déterminer si elle provient de la même session. Évidemment, cette méthode n'est pas fiable. Laissez ensuite le navigateur conserver lui-même l'ID de session. Le navigateur envoie automatiquement l'ID de session à chaque fois qu'une requête http est envoyée. Le mécanisme de cookie est utilisé pour ce faire. Le cookie est un mécanisme utilisé par les navigateurs pour stocker de petites quantités de données. Les données sont stockées sous forme de « clé/valeur ». Lorsque le navigateur envoie une requête http, il joint automatiquement les informations du cookie
Bien entendu, le mécanisme de session Tomcat implémente également les cookies. Visitez Tomcat Lors de l'exécution du serveur, vous pouvez voir un cookie nommé "JSESSIONID" dans le navigateur, qui est l'ID de session conservé par le mécanisme de session Tomcat. Le processus de réponse aux demandes utilisant les cookies est comme indiqué ci-dessous.
3. État de connexion
Avec le mécanisme de session, l'état de connexion est facile à comprendre que la première fois que le navigateur demande au serveur, il doit saisir le nom d'utilisateur et le mot de passe pour vérifier l'identité. Le serveur obtient le nom d'utilisateur et le mot de passe de la base de données. Si la comparaison est correcte, cela signifie que l'utilisateur qui détient actuellement cette session est un utilisateur légitime et que cette session devrait le faire. être marqué comme "autorisé" ou "connecté", etc. Puisqu'il s'agit du statut de la session, il doit être enregistré dans l'objet, Tomcat définit le statut de connexion dans l'objet de session comme suit
<. table border="0">
1
1
2
|
HttpSession session = request.getSession();
session.setAttribute("isLogin",true);
|
2
|
1
2
|
HttpSession session = request.getSession();
session.getAttribute("isLogin");
|
HttpSession session = request.getSession();session.setAttribute("isLogin",true); |
Lorsque l'utilisateur visite à nouveau, Tomcat vérifie l'état de connexion dans l'objet de session
12 |
HttpSession session = request.getSession(); session.getAttribute("isLogin") ; |
Le modèle de serveur de requête du navigateur qui implémente le statut de connexion est décrit dans la figure ci-dessous
Le statut de connexion dans l'objet de session est vérifié chaque fois qu'une ressource protégée est demandée, only isLogin= True session est uniquement accessible, le mécanisme de connexion est donc implémenté.
2. La complexité de plusieurs systèmes
Le système Web s'est longtemps développé d'un système unique dans les temps anciens à un groupe d'applications composé de plusieurs systèmes aujourd'hui. Face à tant de systèmes, les utilisateurs le font-ils. devez-vous y aller un par un ? Vous connecter puis vous déconnecter un par un ? Comme décrit dans l'image ci-dessous
Le système Web est passé d'un système unique à un groupe d'applications composé de plusieurs systèmes. La complexité doit être supportée au sein du système, et non dans le système. utilisateurs. Quelle que soit la complexité interne du système Web, il s'agit d'un tout unifié pour les utilisateurs. Autrement dit, les utilisateurs accédant à l'ensemble du groupe d'applications du système Web équivaut à accéder à un seul système. Une seule connexion/déconnexion suffit. 🎜>
Bien que la solution de connexion à système unique soit parfaite, elle n'est plus adaptée aux groupes d'applications multi-systèmes. Pourquoi ?
Le cœur de la solution de connexion à système unique est le cookie. Le cookie porte l'ID de session pour maintenir l'état de session entre le navigateur et le serveur. Mais il existe des restrictions sur les cookies. Cette restriction concerne le domaine du cookie (correspondant généralement au nom de domaine du site Web). Lorsque le navigateur envoie une requête http, il transportera automatiquement les cookies qui correspondent au domaine, pas tous les cookies
Dans ce cas, pourquoi ne pas unifier les noms de domaine de tous les sous-systèmes du groupe d'applications Web sous un seul nom de domaine de premier niveau, tel que "*.baidu.com", et puis définissez leurs domaines de cookies sur "baidu.com", cette approche est théoriquement possible, et même de nombreuses premières connexions multisystèmes utilisaient cette méthode de partage de cookies avec le même nom de domaine.
Cependant, ce n’est pas parce que c’est possible que c’est bon, et il existe de nombreuses limites au partage de cookies. Tout d'abord, le nom de domaine du groupe d'applications doit être unifié ; deuxièmement, la technologie utilisée par chaque système du groupe d'applications (au moins le serveur web) doit être la même, sinon la valeur clé du cookie (JSESSIONID pour tomcat ) est différent, la session ne peut pas être maintenue et la méthode de partage des cookies ne peut pas être mise en œuvre au-delà des frontières. La connexion aux plateformes technologiques linguistiques, telles que Java, PHP, le système .net ;
Par conséquent, nous avons besoin d'une nouvelle méthode de connexion pour réaliser la connexion de groupes d'applications multi-systèmes, qui est l'authentification unique
3. Authentification unique
Quoi 'est-ce que l'authentification unique ? Cliquez pour vous connecter ? Le nom complet de l'authentification unique est Single Sign On (ci-après dénommé SSO). Cela signifie que si vous vous connectez à un système dans un groupe d'applications multi-systèmes, vous pouvez être autorisé à accéder à tous les autres systèmes sans vous reconnecter. , y compris l'authentification unique et la déconnexion unique
1 Connexion
Par rapport à la connexion à un système unique, l'authentification unique nécessite un centre d'authentification indépendant. Seul le centre d'authentification peut accepter le nom d'utilisateur et le mot de passe de l'utilisateur, entre autres. informations de sécurité. Les autres systèmes ne fournissent pas d’accès de connexion. Seule l’autorisation indirecte du centre de certification est acceptée. L'autorisation indirecte est mise en œuvre via des jetons. Le centre d'authentification SSO vérifie que le nom d'utilisateur et le mot de passe de l'utilisateur sont corrects et crée un jeton d'autorisation lors du processus de saut suivant, le jeton d'autorisation est envoyé en tant que paramètre à chaque sous-système, et le sous-système obtient le jeton d'autorisation. token. , c'est-à-dire que vous êtes autorisé à créer une session partielle. La méthode de connexion à une session partielle est la même que la méthode de connexion à un seul système. Ce processus, qui est le principe de l'authentification unique, est illustré par la figure suivante
Ce qui suit est une brève description de la figure ci-dessus. du système 1. Le système 1 constate que l'utilisateur n'est pas connecté, accède au centre d'authentification sso et utilise sa propre adresse comme paramètre
le centre d'authentification sso constate que l'utilisateur est non connecté, et le sera L'utilisateur est dirigé vers la page de connexion L'utilisateur saisit le nom d'utilisateur et le mot de passe pour soumettre la demande de connexion Le centre de certification sso vérifie les informations des utilisateurs, crée des utilisateurs et s'authentifie sso. La session entre les centres est appelée session globale, et un jeton d'autorisation est créé en même temps Le centre d'authentification sso va accédez à l'adresse de demande initiale (système 1) avec le jeton Le système 1 récupère le jeton et se rend au centre de certification SSO pour vérifier si le jeton est valide Le centre de certification SSO vérifie le jeton, le renvoie valide et enregistre le système 1 Le système 1 utilise le jeton pour créer une session avec l'utilisateur, appelée une session partielle, renvoyant la ressource protégée L'utilisateur accède aux ressources protégées du système 2 -
Le système 2 constate que l'utilisateur n'est pas connecté, accède au centre d'authentification sso et utilise sa propre adresse comme paramètre
L'authentification sso Le centre constate que l'utilisateur est connecté, revenez à l'adresse du système 2 et attachez le jeton
Le système 2 récupère le jeton et se rend au centre de certification SSO pour vérifier si le jeton est valide
Le centre d'authentification SSO vérifie le jeton, renvoie valide, enregistre le système 2
-
Le système 2 utilise le jeton pour créer une session partielle avec l'utilisateur et renvoie les ressources protégées
Une fois que l'utilisateur s'est connecté avec succès, une session sera établie avec le centre d'authentification SSO et chaque sous-système. La session établie par l'utilisateur avec l'authentification SSO. Le centre est appelé session globale, et la session établie par l'utilisateur avec chaque sous-système est appelée session locale, une fois la session locale établie, l'accès de l'utilisateur aux ressources protégées du sous-système ne passera plus par l'authentification SSO. center. La session globale et la session locale ont la relation de contrainte suivante
La session locale existe, et la session globale doit exister
Global. la session existe, la session locale n'existe pas nécessairement
La session globale est détruite, la session locale doit être détruite
Vous pouvez approfondir votre compréhension d'un seul connectez-vous via le processus de connexion de sites Web tels que Blog Park, Baidu, csdn, Taobao, etc. Faites attention à l'URL de saut et aux paramètres pendant le processus de connexion
2. Déconnexion
. Naturellement, l'authentification unique nécessite également une déconnexion unique. Si vous vous déconnectez d'un sous-système, les sessions de tous les sous-systèmes seront détruites. Utilisez la figure suivante pour illustrer
Le. Le centre d'authentification SSO surveille l'état de la session globale. Une fois la session globale détruite, l'auditeur informera tous les systèmes enregistrés d'effectuer des opérations de déconnexion
Ce qui suit est une brève explication de la figure ci-dessus
L'utilisateur lance une demande de déconnexion au système 1
Le système 1 obtient le jeton en fonction de l'ID de session établi entre l'utilisateur et le système 1 et initie une demande de déconnexion au centre d'authentification SSO
Le centre de certification SSO vérifie que le token est valide, détruit la session globale et récupère toutes les adresses système enregistrées avec ce token
- Chaque système d'inscription reçoit la demande de déconnexion du centre d'authentification SSO et détruit la session partielle
- Le centre d'authentification SSO guide l'utilisateur vers la page de connexion
- 4. Schéma de déploiement L'authentification unique implique le centre d'authentification SSO et de nombreux sous-systèmes. Les sous-systèmes et le centre d'authentification SSO doivent communiquer pour échanger des jetons et vérifier. jetons et lancez une demande de déconnexion, le sous-système doit donc intégrer le client SSO. Le centre d'authentification SSO est le serveur SSO. L'ensemble du processus d'authentification unique est essentiellement le processus de communication entre le client SSO et le serveur. décrire
Il existe de nombreuses façons de communiquer entre le centre de certification sso et le client sso. Nous prenons ici le service Web httpClient simple et facile à utiliser. , rpc et restful api peuvent tous être utilisés
5. Implémentation
Ceci est juste une brève introduction au processus d'implémentation basé sur Java. Le code source complet n'est pas fourni une fois que vous avez compris. le principe, je crois que vous pouvez le mettre en œuvre vous-même. sso adopte une architecture client/serveur. Voyons d'abord les fonctions à implémenter par sso-client et sso-server (ci-dessous : sso certification center = sso-server)
sso-client
Interceptez la demande de l'utilisateur non connecté du sous-système et accédez au centre d'authentification sso
- Recevez et stockez le jeton envoyé par le centre d'authentification sso
- Communiquer avec le serveur sso et vérifier la validité du token
- Établir une session locale
- Intercepter le demande de déconnexion de l'utilisateur et l'envoyer à sso Le centre de certification envoie une demande de déconnexion
- Reçoit la demande de déconnexion du centre de certification sso et détruit la session locale
- sso-server
Vérifier les informations de connexion de l'utilisateur
- Créer une session globale
- Créer jeton d'autorisation
- Communiquer avec le client sso et envoyer le jeton
- Vérifier la validité du jeton sso-client
- Enregistrement du système
- Recevez la demande de déconnexion du client sso et déconnectez-vous de toutes les sessions
- Ensuite, implémentons sso étape par étape selon le principe ! 1. sso-client intercepte les requêtes sans connexion
Il existe trois façons pour Java d'intercepter les requêtes : le servlet, le filtre et l'écouteur. Créez une nouvelle classe LoginFilter.java dans sso-client et implémentez l'interface Filter, et ajoutez l'interception des utilisateurs non connectés dans la méthode doFilter()
1
2
3456789101112
public void doFilter (demande ServletRequest, réponse ServletResponse, chaîne FilterChain )lance IOException, ServletException { HttpServletRequest req = (HttpServletRequest) requête ; |
HttpServletResponse res = (HttpServletResponse) réponse ;
HttpSession session = req.getSession();
if(session.getAttribute("isLogin")) {
chain.doFilter(requête, réponse) ;
return;
}
//Aller au centre de certification sso
res.sendRedirect("sso-server-url-with-system - url");
}
|
2. Le serveur sso intercepte les requêtes sans connexion
Intercepte les requêtes de sso- client Accédez à la demande de non-connexion du centre d'authentification sso et accédez à la page de connexion. Ce processus est exactement le même que sso-client
3. > L'utilisateur est sur la page de connexion Entrez le nom d'utilisateur et le mot de passe, demandez la connexion, le centre d'authentification sso vérifie les informations de l'utilisateur, la vérification est réussie et l'état de la session est marqué comme "connecté"
1
1
2
3
4
5
6
|
@RequestMapping("/login")
public String login(String username, String password, HttpServletRequest req) {
this.checkLoginInfo(username, password);
req.getSession().setAttribute("isLogin",true);
return"success";
}
|
234
1 |
String token = UUID.randomUUID().toString(); |
5
6
1
2
3
4
5
6
7
8
9
10
11
|
// 请求附带token参数
String token = req.getParameter("token");
if (token != null) {
// 去sso认证中心校验token
booleanverifyResult = this.verify("sso-server-verify-url", token);
if(!verifyResult) {
res.sendRedirect("sso-server-url");
return;
}
chain.doFilter(request, response);
}
|
|
@RequestMapping("/login")
1
2
|
HttpPost httpPost =new HttpPost("sso-server-verify-url-with-token");
HttpResponse httpResponse = httpClient.execute(httpPost);
|
public String login(String nom d'utilisateur, String mot de passe, HttpServletRequest req) { this .checkLoginInfo(username, password); req.getSession().setAttribute("isLogin",true); return " success";}
4. le serveur sso crée un jeton d'autorisation
1
2
3
|
if (verifyResult) {
session.setAttribute("isLogin",true);
}
|
Le jeton d'autorisation est une chaîne de valeurs aléatoires caractères, peu importe la façon dont il est généré, à condition qu'il soit seulement non répétitif et difficile à falsifier. Voici un exemple
1 |
Jeton de chaîne = UUID.randomUUID().toString();5. Obtenu par le jeton du client sso et la vérification Après vous être connecté au centre d'authentification sso, revenez au sous-système et attachez le jeton. Le sous-système (client sso) obtient le jeton, puis se rend au centre d'authentification sso pour vérification, dans LoginFilter. Ajoutez quelques lignes à la classe doFilter()
12 34567891011 |
// La requête est livrée avec un paramètre de jetonString token = req.getParameter(" token");if (token != null) { / / Accédez au centre de certification sso pour vérifier le token booleanverifyResult = this.verify("sso-server- verify-url", token); if(!verifyResult) { res.sendRedirect("sso-server-url"); return; } chain.doFilter(request, réponse); } La méthode verify() utilise httpClient L'implémentation n'est que brièvement présentée ici Pour une utilisation détaillée de httpClient, veuillez vous référer au document officiel
12 |
HttpPost httpPost =new HttpPost("sso-server-verify-url-with-token"); HttpResponse httpResponse = httpClient.execute(httpPost);6. Le serveur sso reçoit et traite la demande de jeton de vérification L'utilisateur est en sso Une fois que le centre d'authentification s'est connecté avec succès, le serveur sso crée un jeton d'autorisation et stocke le jeton. Par conséquent, sso-server vérifie le jeton pour savoir si le jeton existe et s'il a expiré. Une fois la vérification du jeton réussie, sso-server Le serveur enregistre le système qui envoie la demande de vérification au centre de certification SSO. (c'est-à-dire stocké) Le jeton et l'adresse du système d'enregistrement sont généralement stockés dans une base de données clé-valeur (telle que redis), et redis peut être défini pour la clé. La durée de validité est la période de validité du jeton. Redis s'exécute en mémoire et est très rapide. Il arrive que le serveur sso n'ait pas besoin de conserver de données. Les jetons et les adresses des systèmes d'enregistrement peuvent être stockés dans Redis en utilisant la structure décrite dans la figure ci-dessous. Vous vous demandez peut-être pourquoi devons-nous stocker les adresses de ces systèmes ? S'il n'est pas stocké, cela sera problématique lors de la déconnexion. L'utilisateur soumet une demande de déconnexion au centre d'authentification SSO, et le centre d'authentification SSO se déconnecte de la session globale. Cependant, il ne sait pas quels systèmes ont utilisé cette session globale. pour établir leurs propres sessions locales, ni les sous-sessions auxquelles ils souhaitent envoyer. Le système envoie une demande de déconnexion pour se déconnecter de la session partielle 7. vérifie le jeton et crée avec succès la session partielle Une fois la vérification du jeton réussie, sso- Le client marque la session locale actuelle comme "connectée", modifie LoginFilter.java et ajoute quelques lignes
123 |
if (verifyResult) { session.setAttribute( "isLogin",true);} sso-client doit également lier l'identifiant de session actuelle au jeton, indiquant que l'état de connexion de cette session est lié au jeton. Cette relation peut être enregistrée avec java hashmap, et les données enregistrées sont utilisées pour traiter le. données envoyées par le centre d'authentification sso. Demande de déconnexion
8. Processus de déconnexion
L'utilisateur envoie une demande avec le paramètre "logout" (demande de déconnexion) au sous-système et au client sso. l'intercepteur intercepte la demande et l'initie au centre de certification sso Demande de déconnexion
1
2
3
4
|
String logout = req.getParameter("logout");
if (logout != null) {
this.ssoServer.logout(token);
}
|
12
1
2
3
4
5
6
7
8
|
@RequestMapping("/logout")
public String logout(HttpServletRequest req) {
HttpSession session = req.getSession();
if(session != null) {
session.invalidate();//触发LogoutListener
}
return"redirect:/";
}
|
3
4
|
1
2
3
4
5
6
7
8
|
public class LogoutListener implementsHttpSessionListener {
@Override
publicvoid sessionCreated(HttpSessionEvent event) {}
@Override
publicvoid sessionDestroyed(HttpSessionEvent event) {
//通过httpClient向所有注册系统发送注销请求
}
}
|
String logout = req.getParameter("logout");if (logout != null) { this.ssoServer.logout(token);}
|
Également utilisé par le centre de certification sso De la même manière, il est reconnu que la demande du sso-client est une demande de déconnexion (avec le paramètre "logout"), et le centre d'authentification sso se déconnecte du global session
12 3 456 78 |
@RequestMapping("/logout")public String logout(HttpServletRequest req) { HttpSession session = req.getSession(); if(session != null) { session.invalidate();//Trigger LogoutListener } return"redirect:/";} |
Il existe un centre de certification SSO. L'auditeur de la session globale, une fois la session globale déconnectée, tous les systèmes enregistrés seront invités à se déconnecter
12 345678 |
classe publique LogoutListener implémenteHttpSessionListener { @Override publicvoid sessionCreated (événement HttpSessionEvent) { } @Override publicvoid sessionDestroyed (événement HttpSessionEvent ) { //Envoyer une demande de déconnexion à tous les systèmes d'inscription via httpClient }} |
table>Recommandations associées : Analyse des cookies d'authentification unique en PHP Et mise en œuvrePrincipe d'authentification unique et implémentation simpleMéthode d'implémentation PHP d'authentification unique SSO (framework Laravel)
|
|
|
|
|
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!