Three realizations of single sign-on





Preface

In the B/S system, the login function is usually implemented based on cookies . When the user logs in successfully, the login status is generally recorded in the Session , or a Token is issued to the user . Either way, some information (Session ID or Token) needs to be saved on the client, and the client is required to Carry them in every subsequent request.

In such a scenario, the use of cookies is undoubtedly the most convenient. Therefore, we generally save the Session ID or Token in the Cookie. When the server receives the request, it will verify the information in the Cookie to determine whether the user is logged in.

Single Sign On ( SSO ) means that in multiple application systems under the same account platform, users only need to log in once to access all mutually trusted application systems.

For example, Baidu Tieba and Baidu Maps are two different application systems under Baidu. If a user logs in on Baidu Tieba, he does not need to log in again when he accesses Baidu Maps, then it means that there is a gap between Baidu Tieba and Baidu Maps. Single sign-on is realized.

The essence of single sign-on is to share the login status among multiple application systems . If the user's login status is recorded in the Session, to realize the shared login status, the Session must be shared first. For example, the Session can be serialized to Redis , so that multiple application systems can share the same Redis, and read Redis directly to obtain Session.

Of course, this alone is not enough, because different application systems have different domain names. Although the Session is shared, because the Session ID is often stored in the browser cookie, there are scope restrictions and cannot be passed across domain names , that is Say that when the user logs in to app1.com, the Session ID will only be automatically carried in the request header when the browser visits app1.com, and when the browser visits app2.com, the Session ID will not be carried over. . The key to achieving single sign-on is how to share Session ID (or Token) in multiple domains.



Implementation Method 1: Parent Domain Cookie

Before understanding the specific implementation, let's talk about the scope of Cookie.

The scope of the cookie is determined by the domain attribute and the path attribute . The valid value of the domain attribute is the domain name/IP address of the current domain or its parent domain. In Tomcat, the domain attribute defaults to the domain name/IP address of the current domain. The valid value of the path attribute is the path starting with "/". In Tomcat, the path attribute defaults to the context path of the current Web application.

If the cookie's domain attribute is set to the parent domain of the current domain, then it is considered a parent domain cookie. Cookie has a characteristic, that is, the cookie in the parent domain is shared by the child domain . In other words, the child domain will automatically inherit the cookie in the parent domain .

Using this feature of Cookie, it is not difficult to think that it is not enough to save the Session ID (or Token) in the parent domain. Yes, we only need to Cookie's domain property to the parent domain name (primary domain), while Cookie path attribute set to the root path, so that all the sub-domain applications will have access to the Cookie of .

However, this requires that the domain name of the application system must be established under a common main domain name, such as tieba.baidu.com and map.baidu.com, which are both established under the main domain name of baidu.com, then they can pass this Ways to achieve single sign-on.

Summary: This implementation is relatively simple, but does not support cross-primary domain names.



Realization Method 2: Certification Center

We can deploy a certification center, which is an independent Web service responsible for processing login requests .

The user logs in at the authentication center. After the login is successful, the authentication center records the user's login status and writes the Token into the Cookie . (Note that this cookie belongs to the certification center, and the application system cannot access it.)

The application system checks whether there is a Token in the current request. If not, it means that the user is not logged in in the current system, and then the page is redirected to the authentication center. Since this operation will automatically bring the cookie of the certification center, the certification center can know whether the user has logged in according to the cookie.

If the authentication center finds that the user has not logged in, it will return to the login page and wait for the user to log in. If it finds that the user has already logged in, it will not let the user log in again, but will jump back to the target URL and generate one before the jump Token is spliced ​​behind the target URL and sent back to the target application system.

After the application system gets the Token, it also needs to confirm the legality of the Token with the certification center to prevent users from forging it. After the confirmation is correct, the application system records the user's login status, writes the Token into the Cookie, and then releases the visit. (Note that this cookie is in the current application system and cannot be accessed by other application systems.) When the user accesses the current application system again, it will automatically bring this Token. The application system verifies the Token and finds that the user is logged in, so it will not What happened to the certification center?

Here are the open source implementations of two certification centers by the way:

Apereo CAS is an enterprise-level single sign-on system, where CAS means "Central Authentication Service". It was originally a project of the Yale University Laboratory, and was later transferred to the JASIG organization. The project was renamed JASIG CAS. Later the organization was incorporated into the Apereo Foundation and the project was subsequently renamed Apereo CAS.

XXL-SSO is a simple single sign-on system, personally developed by Xu Xueli, an engineer from Dianping. The code is relatively simple and there is no security control, so it is not recommended to be directly used in the project. It is listed here for reference only.

Summary: This kind of implementation is relatively complicated, supports cross-domain, and has good scalability. It is a standard practice for single sign-on.



Implementation method 3: LocalStorage cross-domain

Earlier, we said that the key to single sign-on is how to share Session ID (or Token) among multiple domains.

Parent domain cookie is indeed a good solution, but does not support cross-domain. So are there any tricks to make cookies pass across domains?

Unfortunately, browsers have increasingly strict cross-domain restrictions on cookies. The Chrome browser also adds a SameSite attribute to Cookies, which almost prohibits the transmission of cookies for cross-domain requests (except hyperlinks), and only when the HTTPs protocol is used, can it be allowed in AJAX cross-domain requests Accept cookies from the server.

However, in the case where the front and back ends are separated, cookies are completely unnecessary. We can choose to save the Session ID (or Token) in the browser's LocalStorage, so that the front-end will take the initiative to save the LocalStorage each time a request is sent to the back-end. The data is passed to the server. These are all controlled by the front-end. All the back-end needs to do is to pass the Session ID (or Token) in the response body to the front-end after the user logs in successfully.

In such a scenario, single sign-on can be implemented at the front end. After the front end gets the Session ID (or Token), in addition to writing it into its own LocalStorage, it can also be written into LocalStorage under multiple other domains by special means.

The key code is as follows:

// 获取 token
var token = result.data.token;

// 动态创建一个不可见的iframe,在iframe中加载一个跨域HTML
var iframe = document.createElement("iframe");
iframe.src = "http://app1.com/localstorage.html";
document.body.append(iframe);
// 使用postMessage()方法将token传递给iframe
setTimeout(function () {
    
    
    iframe.contentWindow.postMessage(token, "http://app1.com");
}, 4000);
setTimeout(function () {
    
    
    iframe.remove();
}, 6000);

// 在这个iframe所加载的HTML中绑定一个事件监听器,当事件被触发时,把接收到的token数据写入localStorage
window.addEventListener('message', function (event) {
    
    
    localStorage.setItem('token', event.data)
}, false);

The front-end uses iframe+postMessage() to write the same Token into LocalStorage under multiple domains. Each time the front-end sends a request to the back-end, it will actively read the Token from LocalStorage and carry it in the request. The same token is shared by multiple domains.

Summary: This implementation is completely controlled by the front-end, almost without back-end participation, and also supports cross-domain.



Supplement: domain name classification

From a professional point of view (according to the definition in "Computer Network"), .com and .cn are first-level domain names (also called top-level domain names), .com.cn and baidu.com are second-level domain names, and sina.com. Cn and tieba.baidu.com are third-level domain names, and so on, N-level domain names are direct subdomains of N-1 level domain names.

From the user's point of view, the main domain name that supports independent filing is generally called the first-level domain name. For example, baidu.com and sina.com.cn can be called the first-level domain name, and the direct sub-domain name established under the main domain name It is called a second-level domain name, such as tieba.baidu.com is a second-level domain name.

In order to avoid ambiguity, I will use the term "primary domain name" instead of "primary domain name".

Guess you like

Origin blog.csdn.net/QiuHaoqian/article/details/112799326