Shiro 处理跨域问题

方法一:

/**
 * @author 李晨亮
 * @date 2020-07-31 17:08
 **/
@Component
public class MyHttpAuthenticationFilter extends BasicHttpAuthenticationFilter {

//    /**
//     * 对跨域提供支持
//     */
//    @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");//标识允许的请求方法
//        // 响应首部 Access-Control-Allow-Headers 用于 preflight request (预检请求)中,列出了将会在正式请求的 Access-Control-Expose-Headers 字段中出现的首部信息。修改为请求首部
//        httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers"));
//        //给option请求直接返回正常状态
//        if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
//            httpServletResponse.setStatus(HttpStatus.OK.value());
//            return false;
//        }
//        return super.preHandle(request, response);
//    }
}

方法二通过过滤器处理跨域问题:
第一步先提前实现ShiroFilterFactoryBean:
设置自定义的过滤器, 配置过滤器,跨域访问时,对OPTIONS的请求返回true,这个很重要,不然不能获取header上的值

 @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 设置自定义的过滤器, 配置过滤器,跨域访问时,对OPTIONS的请求返回true,这个很重要,不然不能获取header上的值
        Map<String, Filter> filters = shiroFilterFactoryBean.getFilters();
        filters.put("authc", new CustomFormAuthenticationFilter());
        filters.put("perms", new CustomPermissionsAuthorizationFilter());

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        //注意过滤器配置顺序 不能颠倒
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了,登出后跳转配置的loginUrl
        filterChainDefinitionMap.put("/user/logout", "logout");
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/user/ajaxLogin", "anon");
        filterChainDefinitionMap.put("/user/login", "anon");
        //pdf授权访问路径对外打开
        filterChainDefinitionMap.put("/fession/ossauth", "anon");
        // 上传图片和视频
        filterChainDefinitionMap.put("/ueditor/getConfig", "anon");
        filterChainDefinitionMap.put("/article/getUploadImgUrl", "anon");
        filterChainDefinitionMap.put("/article/getUploadAdviceUrl", "anon");
        // 查询数据库权限配置
        List<SysResource> resourceList = sysResourceDao.selectAllResource(CoreConstant.AVAILABLE_NORMAL);
        for (SysResource sysResource : resourceList) {
            String path = sysResource.getPath();
            String permission = sysResource.getPermission();
            if (StringUtils.isNotBlank(path) && StringUtils.isNotBlank(permission)) {
                String perm = "perms[" + permission + "]";
                filterChainDefinitionMap.put(path, perm);
            }
        }

        filterChainDefinitionMap.put("/**", "authc");
        //配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据
        shiroFilterFactoryBean.setLoginUrl("/user/login");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
**
 * 自定义认证过滤器
 *
 * @date 2020/7/24 15:54
 */
public class CustomFormAuthenticationFilter extends FormAuthenticationFilter {

    /**
     * 屏蔽OPTIONS请求
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        boolean accessAllowed = super.isAccessAllowed(request, response, mappedValue);
        if (!accessAllowed) {
            // 判断请求是否是options请求
            String method = WebUtils.toHttp(request).getMethod();
            if (StringUtils.equalsIgnoreCase("OPTIONS", method)) {
                return true;
            }
        }
        return super.isAccessAllowed(request, response, mappedValue);
    }

    /**
     * 解决未登录302问题
     *如果shiro没有缓存到的路径是走这里
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        if (isLoginRequest(request, response)) {
            if (isLoginSubmission(request, response)) {
                return executeLogin(request, response);
            } else {
                return true;
            }
        } else {
            // 返回固定的JSON串
            WebUtils.toHttp(response).setContentType("application/json; charset=utf-8");
            WebUtils.toHttp(response).getWriter().print(JSONObject.toJSONString(new Result<>().fali("未登录")));
            return false;
        }
    }

}

**
 * 自定义权限过滤器
 *
 * @date 2020-07-24 15:05
 **/
public class CustomPermissionsAuthorizationFilter extends PermissionsAuthorizationFilter {

    /**
     * 屏蔽OPTIONS请求
     *
     * @param request
     * @param response
     * @param mappedValue
     * @return
     * @throws IOException
     */
    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        // 判断请求是否是options请求
        String method = WebUtils.toHttp(request).getMethod();
        if (StringUtils.equalsIgnoreCase("OPTIONS", method)) {
            return true;
        }
        return super.isAccessAllowed(request, response, mappedValue);
    }

    /**
     * 解决权限不足302问题
     * 如果shiro没有缓存到的路径是走这里
     *
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        Subject subject = getSubject(request, response);
        if (subject.getPrincipal() == null) {
            saveRequestAndRedirectToLogin(request, response);
        } else {
            WebUtils.toHttp(response).setContentType("application/json; charset=utf-8");
            WebUtils.toHttp(response).getWriter().print(JSONObject.toJSONString(new Result<>().fali("无权限")));
        }
        return false;
    }

}

参考:

猜你喜欢

转载自blog.csdn.net/m0_46086429/article/details/107717867