在shiro的记住我中将用户信息principal添加到session中

在shiro的登录中,可以设置rememberMe作为记住我的功能


	<bean id="formAuthenticationFilter"
		class="cn.echo.web.shiro.MyFormAuthenticationFilter">
		
		<property name="usernameParam" value="username" />
		
		<property name="passwordParam" value="password" />
		
		<property name="rememberMeParam" value="rememberMe"/>
		
		<property name="loginUrl" value="/user/login.do"  />
	bean>

但是shiro自带的记住我功能,在用户登录时,并不会把登录的用户的principal放到session中
在非记住我登录时,则会将principal放入session中

protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		//用户帐号
		String username = (String) token.getPrincipal();
		System.out.println(token.getCredentials());
		// 根据用户帐号从数据库取出盐和加密后的值
		// 如果根据账号没有找到用户信息则返回null,shiro抛出异常"账号不存在"
		User user = userService.selectByPrimaryKey(username);
		if(user == null) {
			throw new UnknownAccountException("帐号不存在");
		} else if(user.getActiState().equals(0)) {
			throw new UnknownAccountException("用户未激活!请重新注册!");
		}
		String password = user.getUserPassword();
		String salt = user.getSalt();
		ActiveUser activeUser = new ActiveUser();
		activeUser.setUserId(username);
		activeUser.setUserNickname(user.getUserNickname());
		activeUser.setUserEmail(user.getUserEmail());
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(activeUser, password, ByteSource.Util.bytes(salt), this.getName());
		return authenticationInfo;
	}

其中的activeUser就是principal,在返回后,shiro会将该activeUser添在session中,而在rememberMe时并不会将该principal添加,这样会导致前端获取不到session的user


解决方法:
实现HandlerInterceptor中的preHandle()方法
截取登录时的subject,判断是否是通过rememberMe登录,将principal手动添加到session中

package cn.echo.web.shiro;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import cn.echo.web.pojo.ActiveUser;
import cn.echo.web.pojo.User;
import cn.echo.web.service.UserService;

/**
 * 拦截rememberMe的请求,添加user到session中
 * @author echo
 *
 */
public class RememberMeInterceptor implements HandlerInterceptor {

	 private final Logger logger = Logger.getLogger(RememberMeInterceptor.class);
	
	@Autowired
	private UserService userService;
	
	public RememberMeInterceptor() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
			// 获取session中的subject
		Subject user = SecurityUtils.getSubject();
		
		// 判断是不是通过记住我登录
		if( !user.isAuthenticated() && user.isRemembered()) {
			logger.debug("remembered me, put user in session");
			user.getSession().setAttribute("user", user.getPrincipal());
			
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub

	}

}

你可能感兴趣的:(在shiro的记住我中将用户信息principal添加到session中)