因为前后端分离所以要重写sessionId的获取方式
public class MySessionManager extends DefaultWebSessionManager { /** * * 获取session id * token */ @Override protected Serializable getSessionId(ServletRequest request, ServletResponse response) { // 从请求参数中获取token String token = WebUtils.toHttp(request).getParameter("token"); // 判断是否有值 if (StringUtils.isNoneBlank(token)) { // 设置当前session状态 request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, "url"); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, token); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE); return token; } // 若header获取不到token则尝试从cookie中获取 return super.getSessionId(request, response); }}
把自定义的sessionManager添加到securityManager
@Bean public SecurityManager securityManager() { DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager(); defaultSecurityManager.setRealm(customRealm()); defaultSecurityManager.setSessionManager(defaultWebSessionManager()); return defaultSecurityManager; } @Bean public DefaultWebSessionManager defaultWebSessionManager(){ MySessionManager manager = new MySessionManager(); return manager; }
自定义跳转拦截器
public class RestAuthorizationFilter extends FormAuthenticationFilter { @Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (this.isLoginRequest(request, response)) { if (this.isLoginSubmission(request, response)) { if (log.isTraceEnabled()) { log.trace("Login submission detected. Attempting to execute login."); } return this.executeLogin(request, response); } else { if (log.isTraceEnabled()) { log.trace("Login page view."); } return true; } } else { HttpServletRequest req = (HttpServletRequest)request; HttpServletResponse resp = (HttpServletResponse)response; if (req.getMethod().equals(RequestMethod.OPTIONS.name())) { resp.setStatus(HttpStatus.OK.value()); return true; } else { if (log.isTraceEnabled()) { log.trace("Attempting to access a path which requires authentication. Forwarding to the Authentication url [{}]" ,this.getLoginUrl()); } /** * 在这里实现自己想返回的信息,其他地方和源码一样就可以了 */ resp.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin")); resp.setHeader("Access-Control-Allow-Credentials", "true"); resp.setContentType("application/json; charset=utf-8"); resp.setCharacterEncoding("UTF-8"); PrintWriter out = resp.getWriter(); Result result = new Result(); result.setCode(100001); result.setMessage("用户未登录"); out.println(JSON.toJSONString(result)); out.flush(); out.close(); return false; } } }
shiro引入自定义拦截器
@Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager);// shiroFilterFactoryBean.setLoginUrl("/login");// shiroFilterFactoryBean.setUnauthorizedUrl("/notRole"); Map filterChainDefinitionMap = new LinkedHashMap<>(); // filterChainDefinitionMap.put("/webjars/**", "anon");// filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/loginGet", "anon"); filterChainDefinitionMap.put("/", "anon"); filterChainDefinitionMap.put("/front/**", "anon"); filterChainDefinitionMap.put("/api/**", "anon"); filterChainDefinitionMap.put("/admin/**", "authc"); filterChainDefinitionMap.put("/user/**", "authc"); //主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证 filterChainDefinitionMap.put("/**", "authc"); LinkedHashMap filtsMap = new LinkedHashMap<>(); // 这里使用自定义的filter filtsMap.put("authc", new RestAuthorizationFilter()); shiroFilterFactoryBean.setFilters(filtsMap); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; }
shiro的前后端分离结束
这里分享一个面试的视频资料。私信回复1 ,回复百度网盘链接。别打错了