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

3 篇文章 0 订阅


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

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


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


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

 <form-login 
login-processing-url="/resources/j_spring_security_check" 
login-page="/login" 
authentication-failure-url="/login?login_error=t" 
authentication-success-handler-ref="authenticationSuccessHandler"  />

 <beans:bean id="authenticationSuccessHandler" class="com.sinoparasoft.spring.security.SimpleLoginSuccessHandler">  
    <beans:property name="defaultTargetUrl" value="/"></beans:property>  
    <beans:property name="forwardToDestination" value="true"></beans:property>   
 </beans:bean>  

在处理类中设置将登陆后用户的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配置文件中配置拦截器

    <mvc:interceptors>  
      <!-- session超时 -->  
      <mvc:interceptor>  
        <mvc:mapping path="/**"/>  
        <bean class="Interceptor.RequestInterceptor"> 
         <property name="allowUrls">  
            <list>  
              <!-- 如果请求中包含以下路径,则不进行拦截 -->  
              <value>/resources</value>  
              <value>/login</value>  
            </list>  
          </property>   
        </bean>  
      </mvc:interceptor>  
    </mvc:interceptors>


拦截器代码如下:

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();
		     },    
	 });





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值