shiro+jwt 跨域问题

public class JwtFilter extends BasicHttpAuthenticationFilter {
    /**
     * 跨域支持
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
        httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
        // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
            httpServletResponse.setStatus(HttpStatus.OK.value());
            return false;
        }
        return super.preHandle(request, response);
    }
}

第一个问题是没使用请求头的token 出现了跨域问题 然后我开启了全局跨域

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    /**
     * 基于Servlet的全局配置
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        System.out.println("处理全局跨域");
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("POST","GET","PUT","DELETE")
            .maxAge(1800)
            .allowCredentials(true)
            .allowedHeaders("*")
            .exposedHeaders("L-TOKEN");
    }
}

但是 jwtFilter里面的方法始终都会出现跨域的问题 这是什么情况呢 该怎么解决 看网上说 只要用上面的就可以了 但发现不行

你可以这样试试看

@Configuration
public class GlobalCorsConfig {

    /**
     * 允许跨域调用的过滤器
     */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //允许所有域名进行跨域调用
        config.addAllowedOrigin("*");
        //允许跨越发送cookie
        config.setAllowCredentials(true);
        //放行全部原始头信息
        config.addAllowedHeader("*");
        //允许所有请求方法跨域调用
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

/**
     * 跨域支持
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin"));
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE");
        httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
        // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
            httpServletResponse.setStatus(HttpStatus.OK.value());
            return false;
        }
        return super.preHandle(request, response);
    }

上面14行代码删除,然后重新启动项目,
采纳,谢谢

还需要在前端的配置文件加上这个axios.defaults.withCredentials = true;
而且不要用谷歌引擎

img

修改后还是会有这个问题 能不能给我具体讲讲 jwt拦截跨域和全局跨域要注意的点

看你用JWT应该是做前后端分离吧?shiro的认证,会对你的请求进行拦截,也就是logout、login 等url必须有对应的响应页面,应该是ShiroFilterFactoryBean的配置,没配置authc走RestAuthorizationFilter 过滤器,请参考如下代码:希望对你有帮助。

@Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
           ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
            shiroFilterFactoryBean.setSecurityManager(securityManager);
            // 过滤器链定义映射
            Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
            /*
             * anon:所有url都都可以匿名访问,authc:所有url都必须认证通过才可以访问;
             * 过滤链定义,从上向下顺序执行,authc 应放在 anon 下面
             * */
            filterChainDefinitionMap.put("/login", "anon");
            filterChainDefinitionMap.put("/i18n/**", "anon");
            // 配置不会被拦截的链接 顺序判断,因为前端模板采用了thymeleaf,这里不能直接使用 ("/static/**", "anon")来配置匿名访问,必须配置到每个静态目录
            filterChainDefinitionMap.put("/css/**", "anon");
            filterChainDefinitionMap.put("/fonts/**", "anon");
            filterChainDefinitionMap.put("/img/**", "anon");
            filterChainDefinitionMap.put("/js/**", "anon");
            filterChainDefinitionMap.put("/html/**", "anon");
            // 所有url都必须认证通过才可以访问
            filterChainDefinitionMap.put("/**", "authc");
            // 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了, 位置放在 anon、authc下面
            filterChainDefinitionMap.put("/logout", "logout");
            // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
            // 配器shirot认登录累面地址,前后端分离中登录累面跳转应由前端路由控制,后台仅返回json数据, 对应LoginController中unauth请求
            shiroFilterFactoryBean.setLoginUrl("/un_auth");
            // 登录成功后要跳转的链接, 此项目是前后端分离,故此行注释掉,登录成功之后返回用户基本信息及token给前端
            // shiroFilterFactoryBean.setSuccessUrl("/index");
            // 未授权界面, 对应LoginController中 unauthorized 请求
            shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
            Map<String,Filter>  filters=shiroFilterFactoryBean.getFilters();
            filters.put("authc", new RestAuthorizationFilter());
            shiroFilterFactoryBean.setFilters(filters);
            shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
            return shiroFilterFactoryBean;
    }

从你提供的报错信息判断,需要在18行处理option请求的地方加一个header:
httpServletResponse.setHeader("Access-control-Allow-Credentials", "true");
加上试试看,后续如果还有问题,把浏览器的报错信息提出来。
跨域是浏览器的问题,需要浏览器的报错信息才好定位。