shiro为我们提供了rememberMe功能,也就是记住我功能,这个功能的作用很简单,就是记住我,很多网站上都会有15天免登陆之类的功能,当我们设置了rememberMe功能后,只要登录一次,在不手动退出登录的情况下直接关闭浏览器,然后再次打开浏览器,仍然可以直接访问到属于自己的信息,这里就实现了记住我功能。
public void onSuccessfulLogin(Subject subject, AuthenticationToken token, AuthenticationInfo info) {
//always clear any previous identity:
forgetIdentity(subject);
//如果记住我是true,会执行下面这段代码
if (isRememberMe(token)) {
rememberIdentity(subject, token, info);
} else {
if (log.isDebugEnabled()) {
log.debug("AuthenticationToken did not indicate RememberMe is requested. " +
"RememberMe functionality will not be executed for corresponding account.");
}
}
}
继续深入查看,可以查看到最终调用了CookieRememberMeManager类中部分代码实现了写入cookie
protected void rememberSerializedIdentity(Subject subject, byte[] serialized) {
if (!WebUtils.isHttp(subject)) {
if (log.isDebugEnabled()) {
String msg = "Subject argument is not an HTTP-aware instance. This is required to obtain a servlet " +
"request and response in order to set the rememberMe cookie. Returning immediately and " +
"ignoring rememberMe operation.";
log.debug(msg);
}
return;
}
HttpServletRequest request = WebUtils.getHttpRequest(subject);
HttpServletResponse response = WebUtils.getHttpResponse(subject);
//base 64 encode it and store as a cookie:
String base64 = Base64.encodeToString(serialized);
Cookie template = getCookie(); //the class attribute is really a template for the outgoing cookies
Cookie cookie = new SimpleCookie(template);
cookie.setValue(base64);
cookie.saveTo(request, response);
}
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
if (rememberMe != null) {
token.setRememberMe(rememberMe);
}
try {
// 登录
subject.login(token);
@RequestMapping("/user")
public ReturnMap user() {
return new ReturnMap().success().data("user可以访问");
}
注意要写在 “/**”, "authc"前面
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 拦截器
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// 配置不会被拦截的链接 顺序判断
filterChainDefinitionMap.put("/static/**", "anon");
filterChainDefinitionMap.put("/login", "anon");
// 配置退出 过滤器,其中具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
filterChainDefinitionMap.put("/user", "user");
// 因为目前演示页面依附在此项目下,特为演示页面新增可无权限访问,前后端分离后无需此设置
filterChainDefinitionMap.put("/login.html", "anon");
// <!-- 过滤链定义,从上向下顺序执行,一般将/**放在最为下边 -->因为保存在LinkedHashMap中,顺序很重要
//
filterChainDefinitionMap.put("/**", "authc");// 设置/** 为user后,记住我才会生效
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面,前后端分离设置此为controller返回的未登录的接口
// --------------------------------------------------
// 前后端分离使用下面设置
// shiroFilterFactoryBean.setLoginUrl("/login.html");
shiroFilterFactoryBean.setLoginUrl("/unauthorized");// 前后端分离只需要把需要登录返回告诉前端页面即可
// ---------------------------------------------------
// 登录成功后跳转的链接,前后端分离不用设置
// shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权的界面
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* Cookie 对象 用户免登陆操作,但是需要配置filter /** 权限为user生效
*
* @return
*/
public SimpleCookie rememMeCookie() {
// 初始化设置cookie的名称
SimpleCookie simpleCookie = new SimpleCookie("boot-shiro");
simpleCookie.setMaxAge(2592000);// 设置cookie的生效时间
simpleCookie.setHttpOnly(true);
return simpleCookie;
}
// remeberMe cookie 加密的密钥 各个项目不一样 默认AES算法 密钥长度(128 256 512)
private static final String ENCRYPTION_KEY = "3AvVhmFLUs0KTA3Kprsdag==";
/**
* cookie 管理对象,记住我功能
*
* @return
*/
public CookieRememberMeManager rememberMeManager() {
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememMeCookie());
// remeberMe cookie 加密的密钥 各个项目不一样 默认AES算法 密钥长度(128 256 512)
cookieRememberMeManager.setCipherKey(Base64.decode(ENCRYPTION_KEY));
return cookieRememberMeManager;
}
/**
* 注入 securityManager
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
securityManager.setRememberMeManager(rememberMeManager());//把cookie管理器交给SecurityManager
return securityManager;
}