配置拦截器实现对用户登录的控制


需求是已经登录的用户如果被管理员注销权限,则在网页上的任何下一步操作都会被强制退出,需要重新登录,

并且在系统中同一用户不能重复登录。


实现思路:在网页上的操作分为两种,一种是页面请求,一种是AJAX请求,需要对这两种情况进行分别拦截。首先在用户登录成功后,将该用户的sessionid存入数据库中,之后配置拦截器对所有请求进行拦截,进行session和用户有效性判断,如果当前sessionid和数据库中存储的sessionid相同,则认为用户登录有效,通过拦截器;如果当前sessionid雨数据库中存储的不相同,则认为有重复登录情况,将当前sessionid销毁,跳转到登录界面。


在security配置文件中加入登录成功后进入的处理类

 

   
      
       
   

在处理类中设置将登陆后用户的session存入数据库中

package com.sinoparasoft.spring.security;
import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.sinoparasoft.model.Users;
import com.sinoparasoft.spring.security.tool.GetUserName;

public class SimpleLoginSuccessHandler implements AuthenticationSuccessHandler,InitializingBean {  
      
	private String defaultTargetUrl;  
    
    private boolean forwardToDestination = false;  
    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();  
    @Resource
	GetUserName getusername;
      
    @Transactional(readOnly=false,propagation= Propagation.REQUIRED,rollbackFor={Exception.class})  
    public void saveLoginInfo(HttpServletRequest request,Authentication authentication){  
      
       String username = getusername.username();//获取登录的用户名
   	   String sessionid=request.getSession().getId();//获取登录的SESSIONID
       Users user=Users.FindUserByUsername(username);
       user.setSessionid(sessionid);
	   user.merge();//存入数据库中	 
    	
    	
    }



	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		
	}
	 public void setDefaultTargetUrl(String defaultTargetUrl) {  
	        this.defaultTargetUrl = defaultTargetUrl;  
	    }  
	  
	    public void setForwardToDestination(boolean forwardToDestination) {  
	        this.forwardToDestination = forwardToDestination;  
	    }  


	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		// TODO Auto-generated method stub
		 this.saveLoginInfo(request, authentication);  
		  if(this.forwardToDestination){  
	           
	              
	            request.getRequestDispatcher(this.defaultTargetUrl).forward(request, response);  
	        }else{  
	         
	              
	            this.redirectStrategy.sendRedirect(request, response, this.defaultTargetUrl);  
	        }  
		
	}  
      
    
      
}  

然后在springmvc配置文件中配置拦截器

      
        
        
          
         
           
              
                
              /resources  
              /login  
              
             
          
        
    


拦截器代码如下:

package Interceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.sinoparasoft.model.Users;
import com.sinoparasoft.spring.security.tool.GetUserName;

public class RequestInterceptor extends HandlerInterceptorAdapter {

	@Resource
	GetUserName getusername;
	
	public String[] allowUrls;//还没发现可以直接配置不拦截的资源,所以在代码里面来排除  
    
    public void setAllowUrls(String[] allowUrls) {  
        this.allowUrls = allowUrls;  
    }  
	
	
	
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		
		
		// TODO Auto-generated method stub
		request.setCharacterEncoding("UTF8");
		HttpSession session=request.getSession();//获取登录的SESSION	
		
		
		String sessionid=request.getSession().getId();//获取登录的SESSIONID
		String requestPath=request.getServletPath();//获取客户请求页面
		String username = getusername.username();//获取登录的用户名
		
		if(username.equals("admin"))
		{
			//默认初始超级管理员登录,不判断session
			return true;
		}
		
		 //先过滤掉不需要判断SESSION的请求
		for(String url : allowUrls) {	
            if(requestPath.contains(url)) {    
                return true;    
            }
		}
	

		//判断用户名是否有效
		 if(Users.CheckUsernameExist(username)&&Users.CheckUserEnabled(username))
		  {
			  
			  System.out.println("requestPath:"+requestPath);
			  System.out.println("允许登录");
			    //判断当前sessionid和数据库中的是否一样
			    Users user=Users.FindUserByUsername(username);
			    if(sessionid.equals(user.getSessionid()))
			    {
			    	 System.out.println("与数据库中sessionid相同,登录成功");
			    	return true;
			    }
			    else
			    {
			    	
			    		 session.invalidate();
			    		 System.out.println("有其它用户登录强制退出,登录失败");
			    		 response.sendRedirect("sinoparasoft/");
			    		 return false;
			    	
			    }
			  
		  }
		  else
		  {
			  System.out.println("不允许登录");
			  session.invalidate();
			  response.sendRedirect("sinoparasoft/");
			  return false;
		  }
	}
   
	
	
}

以上基本完成需求,这些实现了页面跳转请求中的拦截,但是在网页中还有一些请求是ajax操作,当用户已经被强制下线后,他再点击ajax请求时,页面会没有任何响应,无法完成页面跳转到登录界面,所以需要在ajax请求完成之后增加complete判断,如果返回的不是success,就刷新当前页面,完成页面跳转请求,这样就可以被拦截器拦截,实现跳回登录页面的目的

$.ajax({
	 type: 'POST',
	 complete: function(XMLHttpRequest, textStatus) { if(textStatus!="success")  location.reload(); },
	 url: '${userpwdchange}' ,
	 data: {userid:userid,username:username,pwd:userpwd},
	 dataType: 'json',
	success: function(data){   
		alert("密码重置为:12345");
		 $('#userchange').modal('hide');
		location.reload();
		     },    
	 });





你可能感兴趣的:(java,js)