shiro权限控制+前后端分离+复杂请求(OPTIONS+POST)遇到的问题

版权声明:欢迎转载 https://blog.csdn.net/feinifi/article/details/85695520

我们知道,shiro做权限控制,能够对请求的url做控制,如果用户未登陆,那么对于有些请求,就会出现禁止访问的情况。

对于前后端分离的项目,存在跨域的问题,shiro做权限控制,也是有解决办法的,就是让前端的所有异步ajax请求带上cookie。比如:

通过xhrFields:{withCredentials:true}属性,我们就让我们的前端跨域 请求带上了cookie,用户登录之后,再作其他请求,会携带cookie,这样服务端,就能根据session来判断用户是否已经登录。否则,会一直以为用户未登陆,拒绝用户请求。

这里ajax请求分为两种,一种是简单请求,就是所有的请求直接请求服务端。他们的contentType类型是:application/x-www-form-urlencodedmultipart/form-datatext/plain三者之一,方法类型type是get,post,head。

还有一种,我们称之为复杂请求,其实也不是什么高深莫测的东西,他们的contentType是application/json,方法类型type是post、patch、delete、put,这些请求在执行的时候,会先往服务器发送一个探测请求,而这个探测请求的方法类型就是OPTIONS,这个请求,默认是不会带上cookie的,而且也无法设置让他带上cookie。通过之前的介绍,我们知道,如果后端在接收到一个请求之后,判断没有携带cookie,或者携带的cookie已经过期,那么他会让这个请求返回错误,不会成功返回状态码200。这样,复杂请求的真正请求就不会到达服务端。所以复杂请求这里就永远也请求不到数据。这就是今天要说的shiro+跨域+复杂请求导致的问题。

在springboot+shiro的项目中,这种问题的解决办法就是,让权限认证控制跳过OPTIONS方法,不让他做认证检查。shiro的过滤器可以自定义,在自定义的filter中,我们可以对onPreHandle这个方法做覆盖。我这里自定义的filter是继承自PassThruAuthenticationFilter,代码如下:

@Override
public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue)
 throws Exception {
    HttpServletRequest req = (HttpServletRequest)request;
    HttpServletResponse res = (HttpServletResponse)response;
    if(req.getMethod().equals(RequestMethod.OPTIONS.name())){
         return true;
    }
    return super.onPreHandle(request, response, mappedValue);
}

这样,我们的复杂请求的安全检查请求上来就直接返回200状态码,接着真正的请求就会上来执行了。如果是springmvc,也是同样的思路,反正就是想方设法在进行认证之前,过滤掉OPTIONS请求。 

以下是配置shiroFilter的Bean。供参考:

猜你喜欢

转载自blog.csdn.net/feinifi/article/details/85695520