栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > Vue.js

Shiro过滤器导致的前端跨域

Vue.js 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Shiro过滤器导致的前端跨域

问题背景

公司项目是前后端分离的,最近要求在请求时都要在请求头加入自定义的 token,在做接口调试时,前端总是请求不通,然而自己用 POSTMAN 等工具时都可以,这就出现了问题,也就是 复杂请求 的跨域问题。

问题分析

部分文段摘自 跨域资源共享 CORS 详解

复杂请求

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。

  • 请求方法是以下三种方法之一:
HEAD
GET
POST
  • HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type: 只限于三个值 application/x-www-form-urlencoded multipart/form-data text/plain

这是为了兼容表单(form),因为历史上表单一直可以发出跨域请求。AJAX 的跨域设计就是,只要表单可以发,AJAX 就可以直接发。

凡是不同时满足上面两个条件,就属于非简单请求。

预检请求

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

过滤器

由于项目中的 shiro 使用了 UserFilter, 下面是其代码:

public class UserFilter extends AccessControlFilter {
    public UserFilter() {
    }

    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
 if (this.isLoginRequest(request, response)) {
     return true;
 } else {
     Subject subject = this.getSubject(request, response);
     return subject.getPrincipal() != null;
 }
    }

    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
 this.saveRequestAndRedirectToLogin(request, response);
 return false;
    }
}

可以看出过滤器在过滤时上面的判断是用来判断是否为登录请求的,否则就去寻找登录凭证。而在 OPTIONS 请求中,是没有携带上 token 信息的,下面是当时情况下请求的 header:

=== MimeHeaders ===
host = 192.168.7.139:4000
connection = keep-alive
accept = *
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
 ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
 // Shiro的核心安全接口,这个属性是必须的
 shiroFilterFactoryBean.setSecurityManager(securityManager);
 // 身份认证失败,则跳转到登录页面的配置
 shiroFilterFactoryBean.setLoginUrl(loginUrl);
 // 权限认证失败,则跳转到指定页面
 shiroFilterFactoryBean.setUnauthorizedUrl(unauthorizedUrl);

 Map filters = new linkedHashMap<>();
 filters.put("user", new StatelessAuthcFilter());
 shiroFilterFactoryBean.setFilters(filters);

 // Shiro连接约束配置,即过滤链的定义
 Map filterChainDefinitionMap = new linkedHashMap<>();
 // 对静态资源设置匿名访问
 filterChainDefinitionMap.put("/favicon.ico**", "anon");
 filterChainDefinitionMap.put("/css
 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");

 this.saveRequestAndRedirectToLogin(request, response);
 return false;
    }

}

这样就解决了 shiro 导致的跨域问题,如果内容对你有所帮助,可以分享给你的好友共同学习。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号