spring boot + shiro 前后端分离做权限控制 bean.setLoginUrl("/auth/unauthentication.do") redirect 跳转登录失效 跨域

一、 直接配置跳转

起先是在ShiroConfiguration里直接这么写的:

bean.setLoginUrl("/auth/unauthentication.do");

前端请求时候报错:

Failed to load http://192.168.1.38:3333/menu/updatePermission.do: Redirect from 'http://192.168.1.38:3333/menu/updatePermission.do' to 'http://192.168.1.38:3333/auth/unauthentication.do;JSESSIONID=ad2cf3a5-7da2-462a-aafb-4ad5ecdafb83' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8020' is therefore not allowed access.

经过多方面的搜集资料,发现这个重定向之后会吧请求头信息清空(其实报错里也清楚)

二、 写自定义shiro的过滤器AuthenticationFilter
刚开始想着绕过跳转,过滤器里不让他跳转,就直接扔个状态码啥的,前端能接收到状态码直接跳转登录页就行了

package com.bole.permission.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bole.body.Body;

public class AuthenticationFilter extends FormAuthenticationFilter {
    Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        WebUtils.toHttp(response).sendError(Body.LOGON_FAILURE.intValue());
        return false;
    }
}

结果:前端收到500错误,状态码也收到了,后台也报错,心里感觉各种别扭,难受,这怎么行

三、 还用重定向试试

经过各种调试,设置请求头,最终成功解决了跨域问题

package com.bole.permission.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AuthenticationFilter extends FormAuthenticationFilter {
    Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class);

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpResp = WebUtils.toHttp(response);
        HttpServletRequest httpReq = WebUtils.toHttp(request);

        /**系统重定向会默认把请求头清空,这里通过拦截器重新设置请求头,解决跨域问题*/
        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");

        WebUtils.toHttp(response).sendRedirect("/auth/unauthentication.do");
        return false;
    }
}

注意:httpResp.addHeader("Access-Control-Allow-Origin", httpReq.getHeader("Origin"));
Origin如果设置*还是不行的,如果指定url,如果多台服务器或者地址有变化还得修改,也不太好,最终用请求的Origin最完美,问题解决!!!

你可能感兴趣的:(技术)