This project briefly introduces the concept and principle of SSO, and then implements a simple SSO system using SpringBoot+Redis. The system uses the form of the ticket, and relies on the cookie to carry the ticket to the sso server for verification. After the verification is passed, the access request address is allowed.
Project address: [https://gitee.com/xgpxg/SSO-DEMO] (https://gitee.com/xgpxg/SSO-DEMO)
SSO (Single Sign On), single sign-on, is simply a system with multiple subsystems, only log in one subsystem, and then do not need to log in again when accessing other subsystems, that is, "once login, multiple places" Access" can effectively enhance the user experience.
The general flow of single sign-on is as follows (based on cookies):
When the user accesses the A system for the first time, the system A finds that the user is not logged in, and then redirects to the SSO authentication center and carries the request url to perform login verification.
The user authenticates the user name and password in the SSO authentication center. After the login is successful, the server generates a ticket, then redirects to the source url of system A and appends the ticket to the url parameter.
System A obtains the ticket in the url parameter, and initiates a ticket comparison to the SSO. If the comparison is successful, the system A releases and stores the ticket into the cookie.
The user accesses the B system. At this time, the B system has carried the ticket under the domain, and directly initiates the ticket test to the SSO. If the test is successful, the release is performed, and the ticket is stored in the cookie (update the ticket expiration time).
When the user logs out, remove the cookie under the domain.
The flow chart is roughly as follows:
The principle is relatively simple, using shared cookie to implement SSO, sso-server uses redis to store user ticket, app-a and app-b use Spring interceptor to filter user requests, each request needs to verify the ticket to sso-server, if the verification fails Redirect to login (with source url).
Use a one-time ticket, that is, a ticket can only be used once, and it will be used immediately after use to ensure the security of the ticket.
Please see the project source code: [https://gitee.com/xgpxg/SSO-DEMO] (https://gitee.com/xgpxg/SSO-DEMO)
**2. How to ensure the security of the ticket? **
This problem has also plagued me for an afternoon, I have been seeking a perfect and secure form of ticket delivery. Finally, I understand that there is no absolute security on the network. When the benefit of cracking it is less than that caused by cracking. When it comes to benefits, he is safe, that is, security is relative. So since the ticket is passed as a cookie or url parameter, its security is not guaranteed. We can guarantee how to compare the ticket. How to verify that the user who gets the same ticket is the same user. For this problem, I used a one-off ticket, which was also mentioned above. Although it does not guarantee absolute security, it can effectively prevent others from directly intercepting cookies and gaining permission.
**3. Doman about cookie **
During the test, the cookie was found to be a second-level domain name, such as aa.test.com instead of test.com, which caused other systems to fail to share the cookie and cause single sign-on failure. The solution is to set the domain to .test directly. .com can be, pay attention to the previous point can not be omitted. Secondly, using the following configuration directly in yml to set the domain of the cookie is invalid.
Server: Servlet: Session: Cookie: Domain: .test.com
**4. When requesting sso-server or requesting subsystem directly when logging out? **
Considering the cookie shared between subsystems, the subsystem's cookie can be cleared.
The domain name used:
#for app-a, port is 8081 127.0.0.1 aa.test.com
#for app-b, port is 8082 127.0.0.1 aa.test.com
#corresponding to sso-server, port is 8080 127.0.0.1 sso.com
Then visit the home page of app-a (http://aa.test.com/home), because it is not logged in, so jump to the login page of sso;
After logging in successfully, it will automatically return to the home interface of app-a. At this time, accessing the home interface of app-b again does not need to log in again.
Log out of the home interface of app-b, and then access the home interface of app-a, then ask to log in again.