springboot集成shiro 前后端分离
前后端分离情况下 首先考虑是否跨域,如果没有跨域是可以使用shiro原生的session+cookie,无需特别处理。
如果涉及到跨域则需要考虑cookie问题(本质上也是重写shiro获取JESSIONID的地方即可)
登陆的时候将生成的的sessionId返回给前端,前端保存之后放在header里面即可,以后请求的时候加一个token,这个字段就是保存的sessionId
@PostMapping("/login") public ResultVO login(User user){ Map<String,String> map = Maps.newHashMap(); Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getUserName(),user.getPassword()); try{ subject.login(usernamePasswordToken); String sessionId = (String) subject.getSession().getId(); map.put("sessionId",sessionId); }catch (Exception e){ log.error(e.getMessage()); } return ResultVOUtil.success(map); }
重写DefaultWebSessionManager获取sessionId的方法
public class MySessionManager extends DefaultWebSessionManager { @Override protected Serializable getSessionId(ServletRequest request, ServletResponse response) { HttpServletRequest httpServletRequest = WebUtils.toHttp(request); String token = httpServletRequest.getHeader("token"); System.out.println("token:"+token); if(!StringUtils.isEmpty(token)){ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, "token"); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, token); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); return token; }else{ return super.getSessionId(request, response); } } }
完整代码见下
package com.palmdrive.lemon.config; import com.palmdrive.lemon.filter.ShiroFormAuthenticationFilter; import com.palmdrive.lemon.shiro.MyShiroRealm; import com.palmdrive.lemon.util.CookieUtil; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.servlet.ShiroHttpServletRequest; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.apache.shiro.web.util.WebUtils; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import javax.servlet.Filter; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.Serializable; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shirFilter(){ System.out.println("shiro-------"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager()); Map<String, Filter> filtersMap = new LinkedHashMap<>(); filtersMap.put("shiroAuthc", new ShiroFormAuthenticationFilter()); shiroFilterFactoryBean.setFilters(filtersMap); Map<String,String> map = new HashMap<String, String>(); //对所有用户认证 map.put("/admin/login", "anon"); map.put("/seller/product/list", "shiroAuthc,perms[product:table:student:view]"); map.put("/**","shiroAuthc"); shiroFilterFactoryBean.setUnauthorizedUrl("/admin/unauth"); shiroFilterFactoryBean.setFilterChainDefinitionMap(map); return shiroFilterFactoryBean; } @Bean public SecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myShiroRealm()); // 自定义session管理 使用redis securityManager.setSessionManager(sessionManager()); // 自定义缓存实现 使用redis // securityManager.setCacheManager(cacheManager()); return securityManager; } @Bean public SessionManager sessionManager() { MySessionManager mySessionManager = new MySessionManager(); return mySessionManager; } @Bean public MyShiroRealm myShiroRealm() { MyShiroRealm myShiroRealm = new MyShiroRealm(); return myShiroRealm; } public class MySessionManager extends DefaultWebSessionManager { @Override protected Serializable getSessionId(ServletRequest request, ServletResponse response) { HttpServletRequest httpServletRequest = WebUtils.toHttp(request); String token = httpServletRequest.getHeader("token"); System.out.println("token:"+token); if(!StringUtils.isEmpty(token)){ request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, "token"); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, token); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); return token; }else{ return super.getSessionId(request, response); } // if(CookieUtil.get(httpServletRequest,"JSESSIONID") != null){ // System.out.println(CookieUtil.get(httpServletRequest,"JSESSIONID").getValue()); // } } } }