背景
最近做一個前后端分離的項目時,使用shiro做權限管理時遇到跨域問題,這里做一下記錄。
原因
后端通過Shiro配置URL過濾,
默認對於沒有授權的訪問請求會redirect至LoginUrl.但在跨域訪問時,redirect失敗.原因是基於安全考慮,redirect發生時Response Header的信息會被清除,導致client端的訪問被server端拒絕.
shiroFilterFactoryBean.setLoginUrl("/unauth");
默認對於沒有授權的訪問請求會redirect至LoginUrl.但在跨域訪問時,redirect失敗.原因是基於安全考慮,redirect發生時Response Header的信息會被清除,導致client端的訪問被server端拒絕.
解決
@Component
public class CORSFilter extends OncePerRequestFilter {
/*
* 在ResponseBodyWrapHandler中已處理跨域問題
* 但是在shiro驗證未通過跳轉/unauth時, 因為redirect 重定向會丟失所有請求頭,跨域問題重新出現
* */
@Override
protected void doFilterInternal(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
HttpServletResponse res = (HttpServletResponse) servletResponse;
res.setContentType("text/html;charset=UTF-8");
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "*");
res.setHeader("Access-Control-Max-Age", "0");
res.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
res.setHeader("Access-Control-Allow-Credentials", "true");
res.setHeader("XDomainRequestAllowed","1");
filterChain.doFilter(servletRequest, servletResponse);
}
}