shiro教程9(session和remember me)

session

  shiro提供的session不依赖web容器,可以直接使用,如果是在web环境下,session中的数据和httpsession中的数据是通的。Shiro中的session可以出现在任何地方,例如service、dao等,不需要从controller中传递session参数,用户保存在session中的数据可以在HTTP session中获取,保存在httpsession中的数据也可以从session中获取。

session常用方法

shiro教程9(session和remember me)_第1张图片

api 说明
startTimestamp session的创建时间;
stopTimestamp session的失效时间;
lastAccessTime session的最近一次访问时间,初始值是startTimestamp
timeout session的有效时长,默认30分钟
attributes session的属性容器
touch 刷新
stop 销毁会话,Subject.logout()时会自动调用stop方法来销毁会

实现登录成功后保存登录信息到session中

创建FormAuthenticationFilter的子类重写onLoginSuccess方法

/**
 * 自定义的表单认证过滤器
 * @author dengp
 *
 */
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter{
	/**
	 * 认证成功后会调用次方法
	 */
	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {
		// 获取登录信息
		String user = (String) subject.getPrincipal();
		System.out.println("登录账户:"+user);
		Session session = subject.getSession();
		session.setAttribute("msg", "自定义FormFilter传递的信息...");
		return super.onLoginSuccess(token, subject, request, response);
	}
}

配置文件中配置


<bean id="customFormAuthenticationFilter" class="com.dpb.filter.CustomFormAuthenticationFilter">
		
		<property name="usernameParam" value="username" />
		<property name="passwordParam" value="password" />
	bean>

	
	<bean class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"
		id="shiro">
		
		<property name="securityManager" ref="securityManager" />
		
		<property name="loginUrl" value="/login.do" />
		
		<property name="successUrl" value="/jsp/success.jsp" />
		
		<property name="unauthorizedUrl" value="/jsp/refuse.jsp" />

		<property name="filters">
			<map>
				<entry key="authc" value-ref="customFormAuthenticationFilter"/>
			map>
		property>
		
		<property name="filterChainDefinitions">
			<value>
				/login.do=authc
				/login.jsp=anon
				/logout=logout
				/**=authc
			value>
		property>
	bean>

shiro教程9(session和remember me)_第2张图片

测试

shiro教程9(session和remember me)_第3张图片shiro教程9(session和remember me)_第4张图片

remember me

  Shiro提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问,基本流程如下:

  1. 首先在登录页面选中RememberMe然后登录成功;如果是浏览器登录,一般会把RememberMe的Cookie写到客户端并保存下来;
  2. 关闭浏览器再重新打开;会发现浏览器还是记住你的;
  3. 访问一般的网页服务器端还是知道你是谁,且能正常访问;

登录表单中添加记住我复选框

<body>
	<form action="login.do" method="post">
		账号:<input type="text" name="username" ><br/>
		密码:<input type="password" name="password"><br/>
		<input type="checkbox" name="rememberMe"/>记住密码<br/>
		<input type="submit" value="提交">
	form>
body>

配置文件中配置


<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
	<constructor-arg value="rememberMe" />
	<property name="httpOnly" value="true" /> 
	
	<property name="maxAge" value="604800" />
bean> 

<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
	<property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" />
	<property name="cookie" ref="rememberMeCookie" />
bean>


<bean class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"
	id="securityManager">
	
	<property name="realm" ref="myRealm" />
	<property name="cacheManager" ref="cacheManager" />
	
	<property name="rememberMeManager" ref="rememberMeManager"/>
bean>

注意:必须配置为 user级别,authc级别的rememberMe没有效果
shiro教程9(session和remember me)_第5张图片
  到此就可以测试了。登录的时候勾选记住密码关闭浏览器,再访问user级别的请求就直接可以访问了。但是因为此时并没有真正的认证,所以此时的session并不能使用,这时我们可以实现一个过滤器。来拦截rememberMe功能的请求即可

创建RememberMe的过滤器

/**
 * 自定义rememberMe的过滤器
 * @author dengp
 *
 */
public class RememberFormAuthenticationFilter extends FormAuthenticationFilter{

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
		Subject subject = getSubject(request, response);
		Session session = subject.getSession();
		// 记住密码,没有登录isAuthenticated()肯定为false
		if(!subject.isAuthenticated()
				&&subject.isRemembered()
				&&session.getAttribute("msg")==null){
			System.out.println("记住的用户是:"+subject.getPrincipal());
			session.setAttribute("msg", "remember中保存的信息");
		}
		return subject.isAuthenticated()||subject.isRemembered();
	}
}

配置文件中修改


<bean class="com.dpb.filter.RememberFormAuthenticationFilter" id="rememberFormAuthenticationFilter">
bean>


<bean class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"
	id="shiro">
	
	<property name="securityManager" ref="securityManager" />
	
	<property name="loginUrl" value="/login.do" />
	
	<property name="successUrl" value="/jsp/success.jsp" />
	
	<property name="unauthorizedUrl" value="/jsp/refuse.jsp" />

	<property name="filters">
		<map>
			<entry key="authc" value-ref="customFormAuthenticationFilter" />
			<entry key="rememberMe" value-ref="rememberFormAuthenticationFilter" />
		map>
	property>
	
	<property name="filterChainDefinitions">
		<value>
			/login.do=authc
			/login.jsp=anon
			/logout=logout
			/**=rememberMe,user 
		value>
	property>
bean>

shiro教程9(session和remember me)_第6张图片
  注意:如果我们在认证的AuthenticationInfo info = new SimpleAuthenticationInfo(user, pwd, credentialsSalt, “myrealm”); 保存的是自定义的对象,那么该对象必须实现Serializable接口,因为该对象要被持久化到cookie中!!!

测试

shiro教程9(session和remember me)_第7张图片

你可能感兴趣的:(shiro专栏)