问题
最近在涉及shiro的项目中,遇到跨域问题:当在shiro filter设置了filterChainDefinitionMap.put(“/**”,”authc”),即所有url访问都需要授权的时候,重写spring自带的WebMvcConfigurerAdapter中的addCorsMappings来实现跨域失效。
原因
主要原因是FormAuthenticationFilter(我这里使用这个授权过滤器)过滤器中,onAccessDenied方法,在spring自带的cors拦截器运行之前就返回了,所以spring自带的拦截器没有修改到header,其次是在前端axios发送的请求中,目前项目没有用token,axios的withCredentials默认为false,即请求不会带cookie,而项目中保存用户登录状态,使用的是session机制,session需要cookie来实现,当withCredentials=false的时候,任何一个请求的jsessionid都是不一样的。
解决方法
重写onAccessDenied
123456789101112131415161718@Overrideprotected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {if (this.isLoginRequest(request, response)) {return !this.isLoginSubmission(request, response) || this.executeLogin(request, response);} else {HttpServletResponse res = (HttpServletResponse) response;HttpServletRequest req = (HttpServletRequest) request;res.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin")); //注意这个地方,不能使用通配符*res.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");res.setHeader("Access-Control-Max-Age", "3600"); //设置过期时间res.setHeader("Access-Control-Allow-Credentials", "true");res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP 1.1.res.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0. response.setHeader("Expires", "0");this.saveRequestAndRedirectToLogin(request, response);return false;}}使axios发送的请求带上cookie
12import axios from 'axios';axios.defaults.withCredentials=true;