SSO principle mechanism

1. Single system login mechanism

 

1. http stateless protocol

The web application adopts the browser/server architecture, and http is used as the communication protocol. HTTP is a stateless protocol. Each request of the browser will be processed independently by the server and will not be associated with previous or subsequent requests. This process is illustrated by the following figure. There is no connection between the three request/response pairs.

3c91a3bf-25d8-4b1f-8e4a-68535c51aaa8

But this also means that any user can access server resources through a browser. If you want to protect some resources of the server, you must restrict browser requests; to restrict browser requests, you must identify browser requests, respond to legitimate requests, and ignore them. Illegal request; to identify a browser request, the browser request status must be known. Since the http protocol is stateless, let the server and browser maintain a state together! This is the session mechanism

2. Session mechanism

When the browser requests the server for the first time, the server creates a session and sends the session id to the browser as part of the response. The browser stores the session id and carries the session id in the subsequent second and third requests. The server knows whether it is the same user by obtaining the session id in the request. This process is illustrated in the following figure. Subsequent requests are associated with the first request.

8a9fb230-d506-4b19-b821-4001c68c4588

The server saves the session object in memory, how does the browser save the session id? You might think of two ways

  1. request parameters
  2. cookie

Taking the session id as the parameter of each request, the server can naturally parse the parameter to obtain the session id when receiving the request, and then judge whether it is from the same session. Obviously, this method is not reliable. Then the browser itself maintains this session id. The browser automatically sends the session id every time an http request is sent, and the cookie mechanism is just used to do this. Cookie is a mechanism used by browsers to store a small amount of data. The data is stored in the form of "key/value", and the browser automatically attaches cookie information when sending http requests.

Of course, the tomcat session mechanism also implements cookies. When accessing the tomcat server, a cookie named "JSESSIONID" can be seen in the browser. This is the session id maintained by the tomcat session mechanism. The request response process using cookies is as follows

518293d9-64b2-459c-9d45-9f353c757d1f

3. Login status

With the session mechanism, the login status is easy to understand. We assume that the first time the browser requests the server, it needs to enter the user name and password to verify the identity. The server gets the user name and password and compares it to the database. The user is a legitimate user, and the session should be marked as "authorized" or "logged in", etc. Since it is the state of the session, it should be saved in the session object. Tomcat sets the login status in the session object as follows

 
HttpSession session = request.getSession();
session.setAttribute("isLogin", true);

When the user accesses again, tomcat checks the login status in the session object

 
HttpSession session = request.getSession();
session.getAttribute("isLogin");

The browser request server model that implements the login state is described in the following figure

70e396fa-1bf2-42f8-a504-ce20306e31fa

The login status in the session object is checked every time a protected resource is requested, only sessions with isLogin=true can access, and the login mechanism is implemented accordingly.

The complexity of multiple systems

The web system has long since developed from a single system to an application group composed of multiple systems. Faced with so many systems, should users log in one by one and then log out one by one? as described below

6dfbb0b1-46c0-4945-a3bf-5f060fa80710

The web system has developed from a single system to an application group composed of multiple systems, and the complexity should be borne by the system rather than the user. No matter how complex the web system is, it is a unified whole for users, that is to say, users accessing the entire application group of the web system are the same as accessing a single system, and logging in/out only once is enough

9fe14ab3-4254-447b-b850-0436e628c254

Although the single-system login solution is perfect, it is no longer suitable for multi-system application groups. Why?

The core of the single system login solution is the cookie, which carries the session id to maintain the session state between the browser and the server. But cookies are limited. This limitation is the domain of the cookie (usually corresponding to the domain name of the website). When the browser sends an http request, it will automatically carry the cookie that matches the domain, not all cookies.

4d58ccfa-0114-486d-bec2-c28f2f9eb513

In this case, why not unify the domain names of all subsystems in the web application group under one top-level domain name, such as "*.baidu.com", and then set their cookie domain to "baidu.com", this approach is theoretically Yes, even in the early days, many multi-system logins adopted this method of sharing cookies with the same domain name.

However, good is not good, and there are many limitations to the way cookies are shared. First, the domain name of the application group must be unified; secondly, the technology used by each system of the application group (at least the web server) must be the same, otherwise the key value of the cookie (JSESSIONID for tomcat) is different, and the session cannot be maintained. The language technology platform logs in, such as between java, php, and .net systems; third, the cookie itself is not secure.

Therefore, we need a new login method to achieve multi-system application group login, which is single sign-on

3. Single sign-on

What is single sign-on? The full name of single sign on is Single Sign On (hereinafter referred to as SSO).

1. Login

Compared with single-system login, sso requires an independent authentication center. Only the authentication center can accept security information such as the user's username and password. Other systems do not provide a login entry, and only accept indirect authorization from the authentication center. Indirect authorization is achieved through tokens. There is no problem with the sso authentication center verifying the user's username and password, creating an authorization token. In the next jump process, the authorization token is sent as a parameter to each subsystem, and the subsystem gets the token. , that is, authorized, you can use this to create a local session, and the local session login method is the same as that of a single system. This process, which is the principle of single sign-on, is illustrated by the following figure

Below is a brief description of the above figure

  1. The user accesses the protected resources of system 1, and system 1 finds that the user is not logged in, jumps to the sso authentication center, and uses its own address as a parameter
  2. The sso authentication center finds that the user is not logged in and guides the user to the login page
  3. User enters username and password to submit login application
  4. The sso authentication center verifies the user information, creates a session between the user and the sso authentication center, which is called a global session, and creates an authorization token at the same time
  5. The sso authentication center takes the token to the initial request address (system 1)
  6. System 1 gets the token and goes to the sso authentication center to check whether the token is valid
  7. The sso authentication center verifies the token, returns valid, and registers system 1
  8. System 1 uses this token to create a session with the user, called a partial session, returning the protected resource
  9. User accesses protected resources of System 2
  10. System 2 finds that the user is not logged in, jumps to the sso authentication center, and uses its own address as a parameter
  11. The sso authentication center finds that the user has logged in, jumps back to the address of system 2, and attaches the token
  12. System 2 gets the token and goes to the sso authentication center to check whether the token is valid
  13. The sso authentication center verifies the token, returns valid, and registers the system 2
  14. System 2 uses the token to create a partial session with the user, returning the protected resource

After the user logs in successfully, a session will be established with the sso authentication center and each subsystem. The session established between the user and the sso authentication center is called a global session, and the session established by the user and each subsystem is called a local session. After the local session is established, the user accesses The protected resources of the subsystem will no longer pass the sso authentication center, and the global session and the local session have the following constraints

  1. The local session exists, the global session must exist
  2. The global session exists, but the local session does not necessarily exist
  3. The global session is destroyed, the local session must be destroyed

You can deepen your understanding of single sign-on through the login process of blog garden, Baidu, csdn, Taobao and other websites, and pay attention to the jump url and parameters during the login process

2. Cancellation

Single sign-on naturally also requires single logout. If you log out in a subsystem, the sessions of all subsystems will be destroyed, as illustrated by the following figure.

3b139d2e-0b83-4a69-b4f2-316adb8997ce

The sso authentication center has been monitoring the status of the global session. Once the global session is destroyed, the listener will notify all registered systems to perform the logout operation.

The following is a brief description of the above figure

  1. The user initiates a logout request to system 1
  2. System 1 obtains the token according to the session id established by the user and system 1, and initiates a logout request to the sso authentication center
  3. The sso authentication center verifies that the token is valid, destroys the global session, and removes all system addresses registered with this token.
  4. The sso certification center initiates a logout request to all registration systems
  5. Each registration system receives the logout request from the sso authentication center and destroys the local session
  6. The sso authentication center guides the user to the login page

4. Deployment diagram

Single sign-on involves the sso authentication center and the public subsystems. The subsystem and the sso authentication center need to communicate to exchange tokens, verify tokens and initiate logout requests. Therefore, the subsystem must integrate the sso client, and the sso authentication center is sso On the server side, the entire single sign-on process is essentially the process of communication between the sso client and the server, which is described in the following figure

fb29685c-487c-42b9-9ceb-6c7ee29e98c9

There are many ways for the sso authentication center to communicate with the sso client. Here we take the simple and easy-to-use httpClient as an example. Web service, rpc, and restful api can all be used.

5. Realization

Just a brief introduction to the implementation process based on java, without providing the complete source code, understand the principle, I believe you can implement it yourself. Sso adopts a client/server architecture. Let's first look at the functions to be implemented by sso-client and sso-server (below: sso authentication center = sso-server)

sso-client

  1. The interception subsystem does not log in user requests, and jumps to the sso authentication center
  2. Receive and store the token sent by the sso authentication center
  3. Communicate with sso-server to verify the validity of the token
  4. Create a local session
  5. Intercept user logout request and send logout request to sso authentication center
  6. Receive the logout request sent by the sso authentication center and destroy the local session

sso-server

  1. Verify the user's login information
  2. Create a global session
  3. Create an authorization token
  4. Communicate with sso-client to send token
  5. Verify the validity of the sso-client token
  6. System registration
  7. Receive sso-client logout request, logout all sessions

Next, let's implement sso step by step according to the principle!

1. sso-client intercepts non-login requests

Java intercepts requests in three ways: servlet, filter, and listener. We use filter. Create a new LoginFilter.java class in sso-client and implement the Filter interface, and add the interception of unlogged users to the doFilter() method

 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    HttpSession session = req.getSession();

    if (session.getAttribute("isLogin")) {
        chain.doFilter(request, response);
        return;
    }
    //Jump to the sso certification center
    res.sendRedirect("sso-server-url-with-system-url");
}

2. sso-server intercepts non-login requests

Intercept non-login requests that jump from sso-client to sso authentication center, and jump to the login page. This process is exactly the same as sso-client

3. sso-server verifies user login information

The user enters the username and password on the login page, requests to log in, the sso authentication center verifies the user information, the verification is successful, and the session status is marked as "logged in"

 
@RequestMapping("/login")
public String login(String username, String password, HttpServletRequest req) {
    this.checkLoginInfo(username, password);
    req.getSession().setAttribute("isLogin", true);
    return "success";
}

4. sso-server creates an authorization token

The authorization token is a string of random characters. It doesn't matter how it is generated, as long as it is not repeated and not easy to forge. The following is an example.

 
String token = UUID.randomUUID().toString();

5. sso-client obtains the token and verifies

After the sso authentication center logs in, jump back to the subsystem and attach the token, the subsystem (sso-client) gets the token, then go to the sso authentication center for verification, and add a few lines to the doFilter() of LoginFilter.java

 
// request with token parameter
String token = req.getParameter("token");
if (token != null) {
    // Go to the sso authentication center to verify the token
    boolean verifyResult = this.verify("sso-server-verify-url", token);
    if (!verifyResult) {
        res.sendRedirect("sso-server-url");
        return;
    }
    chain.doFilter(request, response);
}

The verify() method is implemented using httpClient, which is only briefly introduced here. For details on how to use httpClient, please refer to the official documentation

 
HttpPost httpPost = new HttpPost("sso-server-verify-url-with-token");
HttpResponse httpResponse = httpClient.execute(httpPost);

6. sso-server receives and processes the verification token request

After the user successfully logs in to the sso authentication center, the sso-server creates an authorization token and stores the token. Therefore, the verification of the token by the sso-server is to find out whether the token exists and whether it has expired. The token verification is successful. After the sso-server registers the system sending the verification request to the sso certification center (that is, the meaning of storage)

The token and registration system address are usually stored in a key-value database (such as redis). Redis can set a valid time for the key, that is, the validity period of the token. Redis runs in memory and is very fast, just as sso-server does not need to persist any data.

Tokens and registered system addresses can be stored in redis with the structure described in the figure below. You may ask, why store the addresses of these systems? If it is not stored, it will be troublesome to log out. The user submits a logout request to the sso authentication center, and the sso authentication center logs out the global session, but it does not know which systems have established their own local sessions with this global session, nor which sub-sessions to send to. The system sends a logout request to log out of the local session

3b221593-f9c4-45af-a567-4937786993e8

7. The sso-client verification token successfully creates a local session

After the token verification is successful, sso-client marks the current local session as "logged in", modify LoginFilter.java, and add a few lines

 
if (verifyResult) {
    session.setAttribute("isLogin", true);
}

sso-client also needs to bind the current session id to the token, indicating that the login status of this session is related to the token. This relationship can be saved with the hashmap of java, and the saved data is used to process the logout request sent by the sso authentication center

8. Logout process

The user sends a request with the "logout" parameter (logout request) to the subsystem, and the sso-client interceptor intercepts the request and initiates a logout request to the sso authentication center

 
String logout = req.getParameter("logout");
if (logout != null) {
    this.ssoServer.logout(token);
}

The sso authentication center also recognizes that the sso-client request is a logout request (with the "logout" parameter) in the same way, and the sso authentication center logs out of the global session

 
@RequestMapping("/logout")
public String logout(HttpServletRequest req) {
    HttpSession session = req.getSession();
    if (session != null) {
        session.invalidate();//触发LogoutListener
    }
    return "redirect:/";
}

The sso authentication center has a global session listener. Once the global session is logged out, it will notify all registered systems to log out

 
public class LogoutListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent event) {}
    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        //Send a logout request to all registered systems through httpClient
    }
}

(over)

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326722553&siteId=291194637
sso