shiro提供的session不依赖web容器,可以直接使用,如果是在web环境下,session中的数据和httpsession中的数据是通的。Shiro中的session可以出现在任何地方,例如service、dao等,不需要从controller中传递session参数,用户保存在session中的数据可以在HTTP session中获取,保存在httpsession中的数据也可以从session中获取。
api | 说明 |
---|---|
startTimestamp | session的创建时间; |
stopTimestamp | session的失效时间; |
lastAccessTime | session的最近一次访问时间,初始值是startTimestamp |
timeout | session的有效时长,默认30分钟 |
attributes | session的属性容器 |
touch | 刷新 |
stop | 销毁会话,Subject.logout()时会自动调用stop方法来销毁会 |
/**
* 自定义的表单认证过滤器
* @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提供了记住我(RememberMe)的功能,比如访问如淘宝等一些网站时,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问,基本流程如下:
<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没有效果
到此就可以测试了。登录的时候勾选记住密码关闭浏览器,再访问user级别的请求就直接可以访问了。但是因为此时并没有真正的认证,所以此时的session并不能使用,这时我们可以实现一个过滤器。来拦截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>
注意:如果我们在认证的AuthenticationInfo info = new SimpleAuthenticationInfo(user, pwd, credentialsSalt, “myrealm”); 保存的是自定义的对象,那么该对象必须实现Serializable接口,因为该对象要被持久化到cookie中!!!