One, single system login mechanism 1, HTTP stateless protocol
The Web application uses the Browser/server architecture, HTTP as the communication protocol. HTTP is a stateless protocol, every request of the browser, the server will be processed independently, not associated with the previous or subsequent requests, the process with a description, three requests/response pairs have no connection between
But this also means that any user can access the server resources through the 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, ignore illegal requests, to identify browser requests, must be clear browser request status. Now that the HTTP protocol is stateless, let the server and browser maintain a state together! This is the session mechanism.
2. Session mechanism
The browser first requests the server, the server creates a session, and sends the ID of the session to the browser as part of the response, the browser stores the session ID, and the session ID in the subsequent second and third requests, the server gets the session ID in the request to know if it is the same user, the process with instructions, Subsequent requests have been associated with the first request
The server saves the session object in memory, how does the browser save the session ID? You might think of two ways
Using the session ID as a parameter for each request, the server receives a request to naturally parse the parameter to get the session ID, and to determine whether it is from the same session, it is obvious that this method is not reliable. The browser itself to maintain the session ID bar, each time you send an HTTP request, the browser automatically send the session Id,cookie mechanism is precisely used to do this thing. Cookies are a mechanism used by browsers to store small amounts of data, stored in "Key/value" form, and automatically accompanied by cookie information when the browser sends an HTTP request.
The tomcat session mechanism, of course, also implements the cookie, when accessing the Tomcat server, a cookie called "Jsessionid" is visible in the browser, which is the session ID maintained by the tomcat session mechanism, and the request response process using the cookie
3. Login Status
With the session mechanism, the login state is good to understand, we assume that the browser first request the server needs to enter the user name and password authentication, the server to get the user name password to database comparison, the correct statement that the current holder of this session is a legitimate user, should be marked as "authorized" or "logged in" And so on, since the state of the session, naturally to be saved in the Session object, Tomcat set the login status in the Session object as follows
12 |
HttpSession session = request.getSession(); session.setAttribute( "isLogin" , true ); |
When the user accesses again, Tomcat views the logon status in the Session object
12 |
HttpSession session = request.getSession(); session.getAttribute( "isLogin" ); |
A browser request server model that implements the logon state, as described
The logon state in the Session object is checked each time a protected resource is requested, and only the islogin=true session is accessible, and the login mechanism is implemented.
Ii. Complexity of multiple systems
Web system has long been from the remote single system to become today by a multi-system group of applications, in the face of such a large number of systems, users do not have a login, and then one to write off? It's like the description.
The web system is developed from a single system into a multi-system application group, and the complexity should be borne internally by the system, not by the user. No matter how complex the Web system is, the user is a unified whole, that is, the user access to the web system of the entire application group and access to a single system, login/logoff just once is enough
Although the single-system login solution is perfect, it is no longer applicable for multi-system applications, why?
The core of a single system login solution is Cookie,cookie carries a session ID to maintain session state between the browser and the server. However, the cookie is limited, which is the domain of the cookie (usually the domain name of the website), and the browser will automatically carry a cookie that matches that domain when sending the HTTP request, not all cookies
In this case, it is theoretically possible not to unify the domain names of all subsystems in the Web application group under a single top-level domain name, such as "*.baidu.com", and then set their cookie domain to "baidu.com". Even early many multi-system logins Use this same domain name to share cookies.
However, the possibilities are not good, and there are many limitations to how cookies are shared. First, the application group domain name is unified, second, the application group systems use the technology (at least the Web server) to the same, otherwise the key value of the cookie (Tomcat is Jsessionid) different, unable to maintain the session, the way to share cookies is not able to achieve cross-language technology platform login, For example, between Java, PHP,. NET systems, and thirdly, the cookie itself is unsafe.
Therefore, we need a new login method to achieve the multi-system application group login, this is the single sign-on
Three, single sign-on
What is single sign-on? Single Sign-on (SSO) refers to a system that is logged in to a multi-system application group and can be authorized in all other systems without having to login again.
1. Login
Compared to single-system login, SSO requires a separate authentication center, only the authentication center can accept the user's user name password and other security information, other systems do not provide login portal, only accept the indirect authorization of the Certification center. Indirect authorization through the token implementation, the SSO Authentication Center to verify the user's user name password is not a problem, create an authorization token, in the next jump process, the authorization token as a parameter sent to each subsystem, the subsystem to get the token, that is authorized to create a local session, The local session logon method is the same as the single-system login. This process, that is, the principle of single sign-on, with instructions
The following is a brief description
1234567891011121314 |
user access to System 1 protected resources, System 1 discovers that the user is not logged in, jumps to the SSO Authentication Center, and takes its own address as a parameter sso Authentication Center discovers that the user is not logged in and directs the user to the login page user input username password Submit Login Request sso Authentication Center verifies user information, creates a session between the user and the SSO Authentication Center, called a global session, and creates an authorization token sso Certification center with token jump transfer initial request address (System 1) System 1 Get the token, go to the SSO Authentication Center to verify that the token is valid sso Certification Center Check token, return valid, register system 1 System 1 uses this token to create a session with the user, called a local session, to return the protected resource user access to System 2 protected resources System 2 discovers that the user is not logged in, jumps to the SSO Authentication Center, and takes its own address as a parameter sso Authentication Center discovers that the user is logged in, jumps back to the address of System 2, and attaches a token System 2 Get the token, go to the SSO Authentication Center to verify that the token is valid sso Certification Center Check token, return valid, register System 2 System 2 uses this token to create a local session with the user, returning the protected resource |
After the user has successfully logged in, a session is established with the SSO Authentication Center and each subsystem, the user's session with the SSO Authentication Center is called a global session, the user's session with each subsystem is called a local session, and after the local session is established, the user access subsystem protected resources will no longer pass through the SSO Authentication Center. The global session has the following constraint relationship with a local session
123 |
局部会话存在,全局会话一定存在 全局会话存在,局部会话不一定存在 全局会话销毁,局部会话必须销毁 |
2. Logout
Single Sign-on naturally also to single-point logoff, in a subsystem, all subsystems of the session will be destroyed, with the following diagram to explain
The SSO Authentication Center listens to the status of the global session, and once the global session is destroyed, the listener notifies all registered systems to perform the logoff operation
The following is a brief description
123456 |
用户向系统1发起注销请求 系统1根据用户与系统1建立的会话id拿到令牌,向sso认证中心发起注销请求 sso认证中心校验令牌有效,销毁全局会话,同时取出所有用此令牌注册的系统地址 sso认证中心向所有注册系统发起注销请求 各注册系统接收sso认证中心的注销请求,销毁局部会话 sso认证中心引导用户至登录页面 |
Iv. deployment diagram
Single sign-on involves SSO authentication center and many subsystems, subsystem and SSO Authentication Center need communication to exchange tokens, check tokens and initiate logout requests, so subsystem must integrate SSO client, SSO Authentication Center is SSO service side, The entire single sign-on process is essentially the process of communication between the SSO client and the server, with a description
The SSO Authentication Center communicates with the SSO client in a variety of ways, with the easy-to-use httpclient as an example where Web service, RPC, restful APIs can
V. Realization OF
Just a brief introduction of the implementation process based on Java, do not provide complete source code, understand the principle, I believe you can achieve their own. SSO uses the client/server architecture, and we'll look at what the sso-client and Sso-server are going to do (below: SSO Certification Center =sso-server)
Sso-client
123456 |
拦截子系统未登录用户请求,跳转至sso认证中心 接收并存储sso认证中心发送的令牌 与sso-server通信,校验令牌的有效性 建立局部会话 拦截用户注销请求,向sso认证中心发送注销请求 接收sso认证中心发出的注销请求,销毁局部会话 |
Sso-server
1234567 |
验证用户的登录信息 创建全局会话 创建授权令牌 与sso-client通信发送令牌 校验sso-client令牌有效性 系统注册 接收sso-client注销请求,注销所有会话 |
Next, let's follow the principle step by step to achieve SSO!
1. Sso-client Interception of non-login requests
Java intercepts requests in the form of servlet, filter, listener three ways, we use filter. Create a new Loginfilter.java class in Sso-client and implement the filter interface, adding an interception to the user who is not logged in in the Dofilter () method
123456789101112 |
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
;
}
//跳转至sso认证中心
res.sendRedirect(
"sso-server-url-with-system-url"
);
}
|
2. Sso-server interception of non-login requests
Intercept the non-login request from sso-client to the SSO Certification center and jump to the login page, which is exactly the same as Sso-client
3. Sso-server Verifying user login information
The user enters the user name password in the login page, requests the login, the SSO Authentication Center verifies the user information, verifies the success, and marks the session status as "logged in"
123456 |
@RequestMapping ( "/login " ) public < Code class= "Java Plain" >string login (string username, string password, HttpServletRequest req) { &NBSP;&NBSP;&NBSP;&NBSP; this &NBSP;&NBSP;&NBSP;&NBSP; req.getsession (). SetAttribute ( ,&NBSP; true &NBSP;&NBSP;&NBSP;&NBSP; return "Success" } |
4. Sso-server Create Authorization Token
The authorization token is a string of random characters, in what way the generation has no relationship, as long as not repeating, not easy to forge, the following is an example
1 |
String token = UUID.randomUUID().toString(); |
5. Sso-client Obtain token and verify
After SSO Authentication Center login, jump back to subsystem and attach token, subsystem (sso-client) Get token, then go to SSO Authentication Center checksum, add several lines in Loginfilter.java Dofilter ()
1234567891011 |
// 请求附带token参数
String token = req.getParameter(
"token"
);
if
(token !=
null
) {
// 去sso认证中心校验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 uses the HttpClient implementation, here is only briefly introduced, HttpClient detailed use method please refer to the Official document
12 |
HttpPost httpPost = new HttpPost( "sso-server-verify-url-with-token" ); HttpResponse httpResponse = httpClient.execute(httpPost); |
6. Sso-server receive and process a checksum token request
After the user has successfully logged on in the SSO Authentication Center, Sso-server creates an authorization token and stores the token, so the Sso-server check of the token is to find out if the token exists and whether it expires. After the token check succeeds, Sso-server registers the system that sent the checksum request to the SSO Authentication Center (which means it is stored)
Tokens and registered system addresses are typically stored in a Key-value database (such as Redis), where redis can set a valid time for a key, which is the lifetime of the token. Redis runs in memory very fast, just sso-server no data needs to be persisted.
Tokens and registered system addresses can be stored in Redis using the described structure, and you might ask why do you want to store the addresses of those systems? If you do not store, log off the time of trouble, the user submits a logout request to the SSO Authentication Center, the SSO Authentication Center logs off the global session, but does not know which system has established its own local session with this global session, and does not know which subsystem to send the logoff request to log off the local session
7. Sso-client Checksum token successfully created local session
After the token check succeeds, sso-client marks the current local session as "logged in", modifies Loginfilter.java, adds a few lines
123 |
if (verifyResult) { session.setAttribute( "isLogin" , true ); } |
Sso-client also needs to bind the current session ID to the token, indicating that the login state of the session is associated with the token, which can be saved in Java HashMap, and the saved data is used to process the logout request from the SSO Certification Center.
8. Logout Process
The user sends a request with the "logout" parameter to the subsystem (logoff request), the Sso-client interceptor intercepts the request and initiates a logout request to the SSO Certification Center
1234 |
String logout = req.getParameter( "logout" ); if (logout != null ) { this .ssoServer.logout(token); } |
The SSO Authentication Center also identifies the sso-client request as a logout request (with the "logout" parameter) in the same way, and the SSO Authentication Center logs off the global session
12345678 |
@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 that notifies all registration systems to log off once the global session is logged off
12345678 |
public
class
LogoutListener
implements
HttpSessionListener {
@Override
public
void
sessionCreated(HttpSessionEvent event) {}
@Override
public
void
sessionDestroyed(HttpSessionEvent event) {
//通过httpClient向所有注册系统发送注销请求
}
}
|
Single Sign-on principle and simple implementation