复杂请求
造成复杂请求的原因就是在请求头部添加了token等信息,浏览器会认为是复杂请求。复杂请求的执行过程是有两步的,浏览器会提前发送一个探针请求(也叫预请求)到服务端,这个请求通过以后才会将真正的请求带着header的信息发送出去
预请求被拦截
预请求直接被shiro拦截了,所以真正的请求永远也到不了后台,这个就是问题的关键。此时需要自定义一个拦截器来处理预请求的问题
package com.**.common.shiro.filter;
import org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyShiroAuthFilter extends PassThruAuthenticationFilter {
@Override
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
HttpServletRequest req = (HttpServletRequest)request;
if(req.getMethod().equals(RequestMethod.OPTIONS.name())){
return true;
}
return super.onPreHandle(request, response, mappedValue);
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
HttpServletResponse httpResp = WebUtils.toHttp(response);
HttpServletRequest httpReq = WebUtils.toHttp(request);
/**系统重定向会默认把请求头清空,这里通过拦截器重新设置请求头,解决跨域问题*/
httpResp.addHeader("Access-Control-Allow-Origin", httpReq.getHeader("Origin"));
httpResp.addHeader("Access-Control-Allow-Headers", "*");
httpResp.addHeader("Access-Control-Allow-Methods", "*");
httpResp.addHeader("Access-Control-Allow-Credentials", "true");
WebUtils.toHttp(response).sendRedirect(httpReq.getContextPath()+"/user/unauth");
return false;
}
}
然后在shiro的配置文件中添加过滤器
@Bean
public ShiroFilterFactoryBean shirFilter(DefaultWebSecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager());
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//注意过滤器配置顺序 不能颠倒
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了,登出后跳转配置的loginUrl
filterChainDefinitionMap.put("/user/logout", "logout");
shiroFilterFactoryBean.setLoginUrl("/user/unauth");
filterChainDefinitionMap.put("/user/unauth", "anon");
filterChainDefinitionMap.put("/user/login", "anon");
/**swagger拦截配置*/
filterChainDefinitionMap.put("/swagger-ui.html", "anon");
filterChainDefinitionMap.put("/swagger-resources/**", "anon");
filterChainDefinitionMap.put("/swagger-resources", "anon");
filterChainDefinitionMap.put("/v2/api-docs", "anon");
filterChainDefinitionMap.put("/webjars/springfox-swagger-ui/**", "anon");
Map<String, Filter> filters = new HashMap<>();
filters.put("authc",new MyShiroAuthFilter());
shiroFilterFactoryBean.setFilters(filters);
filterChainDefinitionMap.put("/**", "authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}