The SpringMVC interceptor implements single sign on

  • 2020-11-18 06:12:58
  • OfStack

The single sign-on function is still very important in practical application scenarios, and logically we do not allow one user to perform two operations at the same time. Let's learn about the single sign-on implementation of SpringMVC

The interceptor of SpringMVC is different from the interceptor of Spring. SpringMVC has the entrance of Series 1, DispatcherServlet, and all the requests go through DispatcherServlet, so you only need to play on DispatcherServlet. DispatcherServlet has no proxy, and Controller managed by SpringMVC has no proxy.

1, first to explore the implementation of a basic principle: the function is relatively simple, is for the same 1 web project with 1 time only have one user in the operation, so it is involved in the discovery of a long-distance login, and here is to launch two roads, one is to find the logged-in user through another server 1 IP perform the login operation again, and then take the initiative to push a reminder 1 user login account different ground; 2 is when the user finds out that his/her account has been bumped out and he/she has another login. As for these two schemes, the first one is relatively real-time but is still under investigation. The following focuses on the first and the second.

2, implement the second is more simple, the two operations, 1 is in the user table 1 more fields, used to store the logged in user's SessionId, because every one request request corresponding to 1 to 1 don't repeat Sessionid, then what is using interceptor technology, to the operation of the user to intercept, first in the interceptor is to release of relevant url login page request, then there is the login check request has been submitted. Finally, filtering to the customer, (about user login, when the authentication is successful, not only to the user in the Session used to login to the validation of the intercept, also need to stock the Session ID user table corresponding Sessionid) for the requested request available Session ID and then according to this ID comparing with database Sessionid whether the same is given by the same, different login indicates that jump out, Because will exist in the operation of the 1 users connect to the server every time a Session just Session not expired user initiated operations request Session id are 1 to so will be and when logging into id match in the database, when others by other devices used to set up an account to log in with Session will refresh the database Sessionid and own Sessionid or constant, but Session has changed in the database, So check the database in the interceptor Sessionid whether one will fail to intercept the user operation to achieve the function of the single user login, (about Session shows that when the user first connects to the server will create a Session on the server side, and then every time 1 user initiated operation request will carry the Session id and appear in 1 case Session failure, the user for a long time not to the server, the user logged on active let Session failure, the user closes the browser, or a server restart)

Here is the implementation of the interceptor in SpringMVC


public class SingleUserInterceptor implements HandlerInterceptor {
	@Autowired
	private userMapper mapper;
	public void afterCompletion(HttpServletRequest arg0,
	HttpServletResponse arg1, Object arg2, Exception arg3)
	throws Exception {
		// TODO Auto-generated method stub
	}
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
	Object arg2, ModelAndView arg3) throws Exception {
		// TODO Auto-generated method stub
	}
	public Boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
	Object arg2) throws Exception {
		String url = arg0.getRequestURI();
		// Release if the page is blocked for login  
		if(url.indexOf("login.jsp")>=0||url.indexOf("new/login")>=0||url.indexOf("checkuser")>=0){
			return true;
		}
		// If user name exists secure (login release)  
		Integer user = (Integer) arg0.getSession().getAttribute("user");
		if(user!=null){
			String sessionid = mapper.getUserEntity(Integer.valueOf(user)).getSessionid();
			if(sessionid.equals(arg0.getSession().getId())){
				return true;
			} else{
				arg1.setStatus(arg1.SC_GATEWAY_TIMEOUT);
				arg1.setContentType("text/html; charset=utf-8");
				PrintWriter out = arg1.getWriter();
				out.println("<html>");
				out.println("<script>");
				out.println("alert(' Your account is logged in elsewhere and you are forced to log off ')");
				out.println("window.open ('" + arg0.getContextPath()
				+ "/new/login','_top');");
				out.println("</script>");
				out.println("</html>");
				// arg0.getRequestDispatcher("login.jsp").forward(arg0, arg1);
				return false;
			}
		}
		arg0.getRequestDispatcher("login.jsp").forward(arg0, arg1);
		return false;
	}
}

The above code can realize the function that when the same user logs in for several times, the first logon user will be squeezed off the line during the operation. It can realize the function of first prompting the account to log in in another place, and then jumping to the login page. Here to explain the main points of the simple alert prompt function if it wants to appear when the alert must be able to request to finish it, then output response print function that alert hint statements, so comment out that jump statement can't be, there is not a alert tips statement, because you do not have the right to the end of the operation but is forwarded or redirected to other operation whether correct or not were other action output to the page, so you won't appear response print statements. So the correct approach is: the interception request is not released (returnfalse), the request is still the original request, will not jump, and response back page print information can be displayed, for the jump login page can be used: out.println ('"+ ES69en0.getContextPath ()+"/new/login','_top'); ); That is, 1 action request is executed in the 1 section js output by response, pointing to the login page.

Through the code above is basically realized the function of single user logged in, but will find ajax requested operation is not able to login in other cities to the login page and no prompt information, first one reason, because your ajax in an asynchronous request, but also match the request in the processor mapper url so it will be seen as the request is successful (return a status code of 200) and the above response printed js statement will become success request is successful, the return value, you can try 1 under the above this sentence: arg1.setStatus(arg1.SC_GATEWAY_TIMEOUT); Commented out. There are a few other things you need to do, starting with the statement arg1.setStatus (arg1.SC_ES95en_TIMEOUT); His function is to set the status code returned by response. The above setting means that the status code 504 will be returned to represent the error of the request. At this time, the ajax request will no longer respond to the success method, but will respond to the error method of ajax.


 $.ajax({
  url:'new/msd2',
  success:function(a){
  alert(a);
  },
  error:function(rs){
  if(rs.status==504){
  document.write(rs.responseText);
  }
  }
  }); 

Set arg1.setStatus (arg1.es111EN_ES112en_ES113en) when ajax request is blocked due to remote login. The return status of the request can be changed to 504 error, and then error method will respond, and document. write(ES117en. responseText) when the status is determined to be the status code set by itself; responseText is the js statement printed to the foreground in the interceptor. For these statements to execute, document.write () is required. Method to write that code to dom to make it work, so far, all requests, asynchronous ajax requests for single sign-on have been basically implemented.

Leave this article to record only the key code and the thought and principle of operation

conclusion

That's it for the SpringMVC interceptor implementation, and I hope you found it helpful. If there is any deficiency, please let me know. Thank you for your support to this site.


Related articles: