- shiro记住我功能原理
采用记住我功能之后,shiro会在cookie中,添加rememberMe属性值。
关闭浏览器之后,cookie信息没有清空,再次打开浏览器,进行访问。
shiro读取rememberMe,其值是用户的唯一标识进行Base64编码后的结果。
shiro对rememberMe值进行解码,解码之后,将该值添加至subject对象中。
- 场景
Base64编码不是加密算法,不安全。shiro的FormAuthenticationFilter,会对记住我的用户,认证不通过。
问题:使用记住我的功能以后,重新打开浏览器,再次访问,如何通过FormAuthenticationFilter认证?并且,web应用程序 ,如何获取当前已认证过用户?
解决办法:重写isAccessAllowed方法。
- 实现
- 自定义filter,继承FormAuthenticationFilter,并且重写isAccessAllowed方法
CrmFormAuthenticationFilter.java
package com.bjsxt.shiro.filter;
import javax.servlet.ServletRequest; import javax.servlet.ServletResponse;
import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; import org.springframework.beans.factory.annotation.Autowired;
import com.bjsxt.pojo.User; import com.bjsxt.service.UserService;
public class CrmFormAuthenticationFilter extends FormAuthenticationFilter {
@Autowired UserService userService;
/** * 重写isAccessAllowed * 是否允许访问 * true:表示通过 * false:表示不通过 */ @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { //获取记住我的用户名 Subject subject = getSubject(request, response); String username = (String)subject.getPrincipal();
//没有认证通过,并且使用了记住我的功能,根据用户名,查询出用户 if(!subject.isAuthenticated() && subject.isRemembered()){ //根据用户名,从数据库查询出用户 User user = userService.findUserByName(username); if(user!=null){ //true表示,如果当前有session,则直接调用 ,如果没有session,则创建一个。与getSession()等效 //false表示,如果当前有session,则直接调用 ,如果没有session,返回null Session session = subject.getSession(true); //将用户添加至shiro session session.setAttribute("currentUser", user); return true; } }
return super.isAccessAllowed(request, response, mappedValue); }
}
|
- 配置filterChains
applicationContext-shiro.xml
<!-- 4.注入filter --> <bean id="crmFormAuthenticationFilter" class="com.bjsxt.shiro.filter.CrmFormAuthenticationFilter"></bean> <!-- 5.配置 shiro filter 与web.xml中的过滤器名称一致 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 指定安全管理器 --> <property name="securityManager" ref="securityManager"></property> <!-- 指定登录的url --> <property name="loginUrl" value="/login" /> <!-- 认证成功访问的url --> <property name="successUrl" value="/index" /> <!-- 授权失败 访问的url --> <property name="unauthorizedUrl" value="/login" /> <!-- 指定key为authc的filter --> <property name="filters"> <map> <entry key="authc" value-ref="crmFormAuthenticationFilter"/> </map> </property> <!-- 过滤链 --> <property name="filterChainDefinitions"> <!-- anon表示无需进行认证,即可访问,相当于游客 authc表示必须经过认证才可访问 --> <value> /login=anon /user/login=anon /template/**=anon /DatePicker/**=anon /layer/**=anon /logout=logout /index=authc /**=user </value> </property> </bean> |
- 程序测试