shiro(14)- 跨域预检请求进行权限认证

跨域问题系列文章

1. 同源策略与CORS(跨域请求的起源)
2. SpringBoot2.x整合CORS解决跨域问题(两种方案)
3. 跨域预检请求进行权限认证(复杂跨域请求的处理)
4. Filter返回失败如何使用CORS配置(SendError和setStatus的区别)

本文重点:对于复制的跨域请求,浏览器会发送一个OPTIONS预检请求,shiroFilter应如何处理该预检请求?

由于浏览器都实行了“同源策略”,限制从一个源加载的文档或脚本去另外一个源进行资源交互。这就会导致前后端分离的架构,前端服务器与后台服务器之间存在着跨域问题。

1. CORS解决跨域

解决跨域问题的核心:允许两个源之间进行资源共享(CORS-跨域资源共享),也就是说,在响应中,添加某些字段。从而放开限制。
CORS如何解决ajax跨域问题

CORS把HTTP请求分为了两类,不同的类按不同的策略进行跨域资源共享的协商。

请求若是POST/GET方式,并且只是含有Accept(浏览器期待的返回类型)、Accept-Language、Content-Language、Content-Type(浏览器参数类型);并且Content-Type只能是application/x-www-form-urlencoded、 multipart/form-data、 text/plain时,才是一个简单的跨域请求。

详解——简单复杂跨域请求的区别

1. 简单的跨域请求

  1. 对于简单的跨域请求,浏览器自动在HTTP请求中添加Origin Header。
  2. 服务器收到一个简单跨域请求后,根据资源权限配置,在响应头中添加Access-Control-Allow-Origin Header。
  3. 浏览器收到响应后,查看Access-Controller-Allow-Origin Header,若当前域得到授权,则将结果返回给JavaScript。否则浏览器忽略此次响应。

2. 复杂的跨域请求

  1. 浏览器发送真实HTTP请求之前先发送一个OPTIONS的预检请求,预检服务器端是否支持真实请求进行跨域资源共享。
  2. 服务器收到OPTIONS请求后,其他拦截器应该快速放行,并且在CORS Filter中,校验Origin字段是否符合预期,是否添加跨域资源共享的响应字段。
  3. 浏览器会根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问
    注:这个过程对于真实请求的调用者(浏览器)来说是透明的。

Access-Control-Allow-Credentials。HTTP响应头,凡是浏览器请求中携带了身份信息,而响应头中没有返回Access-Control-Allow-Credentials: true的,浏览器都会忽略此次响应。

2. shiro和跨域请求

CORS解决跨域请求,其过程对于浏览器(也就是前端)来说是透明的,故需要服务器端进行设置。

对于跨域请求,实际上我们可以添加一个拦截器,设置响应头中的信息。完成跨域授权。

在使用shiro进行权限控制的时候,对于预检请求,我们应该无条件的进行放行,而对于浏览器真实的请求,我们才可以进行安全控制。

故,我们在shiro自定义的拦截器链中,针对OPTIONS请求的方法,需要直接放行。而不需要认证处理

public class MyAuthcFilter extends AccessControlFilter {
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        //若是预检请求,直接放行
        if (StringUtils.equalsIgnoreCase("OPTIONS", ((ShiroHttpServletRequest) request).getMethod()) {
            return true;
        }
        //业务逻辑
        return false;
    }

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

系列文章

shiro安全控制目录

推荐阅读

shiro实现无状态的会话,带源码分析

你可能感兴趣的:(shiro(14)- 跨域预检请求进行权限认证)