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

在Shiro的记住我功能中,默认仅在非记住我登录时会将用户principal放入session。为了解决rememberMe登录时前端获取不到session中user的问题,可以实现HandlerInterceptor的preHandle()方法,检查登录方式,手动将principal添加到session,确保用户信息的完整传递。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

<!-- 基于Form表单的身份验证过滤器,不配置将也会注册此过虑器,表单中的用户账号、密码及loginurl将采用默认值,建议配置 -->
	<bean id="formAuthenticationFilter"
		class="cn.echo.web.shiro.MyFormAuthenticationFilter">
		<!-- 表单中账号的input名称 -->
		<property name="usernameParam" value="username" />
		<!-- 表单中密码的input名称 -->
		<property name="passwordParam" value="password" />
		<!-- 记住我,存cookie -->
		<property name="rememberMeParam" value="rememberMe"/>
		<!-- loginurl:用户登陆地址,此地址是可以http访问的url地址 -->
		<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

	}

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值