标题spring boot+shiro 记住我 会话失效(已解决)
看了很多博客,发现大部分都是使用拦截器。个人感觉还是非常繁琐的,所以自己也做了一个比较简单的。
- 自定义一个过滤器,代码的意思注释写的很清楚了
package com.example.demo.filter;
import com.example.demo.entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.servlet.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
Subject subject = SecurityUtils.getSubject();
//判断用户是通过记住我功能自动登录,此时session失效
if (subject.isRemembered()) {
try {
User user = (User)(subject.getPrincipals().getPrimaryPrincipal());
HttpSession session = ((HttpServletRequest)request).getSession();
if(session.getAttribute("user")==null){
session.setAttribute("user", user);
//设置会话的过期时间--ms,默认是30分钟,设置负数表示永不过期
/*session.setTimeout(-1000l);*/
}
} catch (Exception e) {
e.printStackTrace();
}
}
filterChain.doFilter(request,response);
}
}
- 在ShiroConfig 类中实例化一个Bean
/**
1. 此方法把该过滤器实例化成一个bean,否则在拦截器里无法注入其它bean
2. 没有亲自操作过,看别人的代码这样说的
3. @return
*/
@Bean
public SessionFilter sessionFilter(){return new SessionFilter();}
- 在shiro过滤器对象中将自定义的过滤器对象加入里面,代码位置在return 上方
/**
* shiro过滤器对象
* @param securityManager
* @return
*/
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){
System.out.println("ShiroConfiguration.shiroFilter():配置权限控制规则");
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
//必须设置SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
//如果不设置默认页面会自动找到login页面
shiroFilterFactoryBean.setLoginUrl("/login");
//登录成功后要跳转的页面
shiroFilterFactoryBean.setSuccessUrl("/main");
//未授权页面
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
//添加到shiro内置过滤器,实现权限相关的uri拦截
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
//配置不会被拦截的连接
filterChainDefinitionMap.put("/favicon.ico","anon");
filterChainDefinitionMap.put("/css/**","anon");
filterChainDefinitionMap.put("/fonts/**","anon");
filterChainDefinitionMap.put("/images/**","anon");
filterChainDefinitionMap.put("/js/**","anon");
filterChainDefinitionMap.put("/localcss/**","anon");
filterChainDefinitionMap.put("/dologin/**","anon");
//配置推出过滤器,其中的具体推出代码Shiro已经帮我们实现了
filterChainDefinitionMap.put("/logout","logout");
/*过滤链定义,放在最下边
authc: 所有的url都不许,认证通过后才可以访问;anon:所有的url都可以匿名访问
user:表示记住我或认证通过才可以访问*/
filterChainDefinitionMap.put("/**","user");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
//创建一个Map类型的对象存储自定义的sessionFilter(),添加到shiroFilterFactoryBean
Map<String, Filter> filters = new HashMap<String,Filter>();
filters.put("sessionFilter",sessionFilter());
shiroFilterFactoryBean.setFilters(filters);
return shiroFilterFactoryBean;
}
到此就结束了,好用的话请留言 ,有更好的方法请私信我。