由于shiro使用redirect进行url的跳转,在遇到前端界面与后台业务处理不在一个域名下时,会遇到跨域问题,我们在使用springBoot时,一般会增加一个configuration类的问题允许进行跨跨请求,代码如下所示:
@Configuration
public class WebConfig extends DefaultWebMvcConfig {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowedHeaders("*")
.allowCredentials(true).maxAge(3600);
}
}
但实际上这只解决简单http请求的跨域问题,遇到method=delete/put等非简单请求时,由于浏览器在访问后台服务前,会先发priflight请求(method=options),这时仍然会遇到跨域问题,为了解决priflight的请求问题,我们需要定义一个filter,对priflight的请求直接返回200,表示服务器允许priflight请求;对应的filter如下(使用该filter后,上面的configuration可以省略):
@Order(-100)
@Component
@ServletComponentScan
@WebFilter(urlPatterns = "/*",filterName = "shiroLoginFilter")
public class ShiroLoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
// 允许哪些Origin发起跨域请求
String orgin = request.getHeader("Origin");
// response.setHeader( "Access-Control-Allow-Origin", config.getInitParameter( "AccessControlAllowOrigin" ) );
response.setHeader( "Access-Control-Allow-Origin", orgin );
// 允许请求的方法
response.setHeader( "Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE,PUT" );
//多少秒内,不需要再发送预检验请求,可以缓存该结果
response.setHeader( "Access-Control-Max-Age", "3600" );
// 表明它允许跨域请求包含xxx头
response.setHeader( "Access-Control-Allow-Headers", "x-auth-token,Origin,Access-Token,X-Requested-With,Content-Type, Accept" );
//是否允许浏览器携带用户身份信息(cookie)
response.setHeader( "Access-Control-Allow-Credentials", "true" );
//prefight请求
if (request.getMethod().equals( "OPTIONS" )) {
response.setStatus( 200 );
return;
}
chain.doFilter( servletRequest, response );
}
@Override
public void destroy() {
}
}