shiro拦截导致跨域,文件上传不成功

先上解决办法

package com.mengruan.webbackage.config;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.springframework.context.annotation.Configuration;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @program: hst-website
 * @Description: shiro拦截导致跨域
 * @Author: zzy
 * @create: 2020-04-26 12: 34
 */
@Configuration
public class MyFormAuthenticationFilter extends FormAuthenticationFilter {
    
    
    /**
     * 在访问controller前判断是否登录,返回json,不进行重定向。
     * @param request
     * @param response
     * @return true-继续往下执行,false-该filter过滤器已经处理,不继续执行其他过滤器
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
    
    
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        if (isAjax(request)) {
    
    
            httpServletResponse.setCharacterEncoding("UTF-8");
            httpServletResponse.setContentType("application/json");
            //解决一下跨域问题
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
            httpServletResponse.setHeader("Access-Control-Max-Age", "0");
            httpServletResponse.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");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpServletResponse.setHeader("XDomainRequestAllowed","1");
           
            httpServletResponse.getWriter().flush();
            httpServletResponse.getWriter().close();
        } else {
    
    
            /**
             * @Mark 非ajax请求重定向为登录页面
             */
            //httpServletResponse.sendRedirect("/login");
        }
        return false;
    }

    //解决OPTIONS请求跨域问题
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
    
    
        if (request instanceof HttpServletRequest) {
    
    
            if (((HttpServletRequest) request).getMethod().toUpperCase().equals("OPTIONS")) {
    
    
                return true;
            }
        }
        return super.isAccessAllowed(request, response, mappedValue);
    }


    private boolean isAjax(ServletRequest request){
    
    
        String header = ((HttpServletRequest) request).getHeader("X-Requested-With");
        if("XMLHttpRequest".equalsIgnoreCase(header)){
    
    
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

}

在shiro配置类配置进去

        shiroFilterFactoryBean.getFilters().put("authc", new MyFormAuthenticationFilter());

但此时上传文件还是会不成功,因为shiro包装了request 所有关于multipart请求都被拦截了 ,所以我们需要将文件上传路径不做拦截,或者将request 强转为 MultipartHttpServletRequest

        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/companydynamic/**", "authc");
        filterChainDefinitionMap.put("/customerexample/**", "authc");
        filterChainDefinitionMap.put("/messageboard/**", "authc");
        filterChainDefinitionMap.put("/moudle/**", "authc");
        filterChainDefinitionMap.put("/navigationimg/**", "authc");
        filterChainDefinitionMap.put("/solutionproject/**", "authc");
        //filterChainDefinitionMap.put("/uploadfile/**", "authc");//文件上传路径

以上代码是shiro用于拦截请求的,但是配置了springboot跨域以后,访问以上链接仍然会跨域。因为浏览器在访问服务端是会先发起一个method为OPTIONS的请求,这个请求我们可以简单理解为一个探路请求, 该请求不携带信息, 只是为了测试一下目标服务器是否支持跨域,如果支持跨域的话,再发出后续的请求。
而shiro配置了拦截以后,会预先拦截此OPTIONS请求,然而此OPTIONS并未携带token或者cookie,shiro会鉴权失败,导致浏览器认为服务端不支持跨域。

猜你喜欢

转载自blog.csdn.net/qq_27275851/article/details/105772911