SpringBoot中Shiro处理ajax请求(重写UserFilter)

摘要:
首先,我道歉并在没有经过充分测试的情况下发送了文件。后来,在审查过程中,我发现地图中的同一个键中有两个对象,因此只有最后一个对象有效。在阅读了Shiro相关文档后,我找到了一个有效的解决方案。在文章的最后,我将添加Shiro自己的拦截器相关内容,并编写一个继承org.apache的Shiro过滤器。希罗。网状物滤器授权。UserFilterinportcom。zzyk。常见的模型沃。消息

首先道歉 没经过充分的测试就发文了 后来在review的时候发现我在map中同一个key塞了俩对象

这样只有最后添加的有效 在看了shiro相关文档之后找到了有效的解决方法

文章末尾我会补上Shiro自带的拦截器相关内容

写一个Shiro的过滤器 继承org.apache.shiro.web.filter.authc.UserFilter

import com.zzyk.common.model.vo.Message;
import com.alibaba.fastjson.JSON;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.UserFilter;

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

public class GenericFilter extends UserFilter {

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        resp.setCharacterEncoding("UTF-8");
        resp.setHeader("ContentType", "text/html;charset=UTF-8");
        String requestedWith = req.getHeader("X-Requested-With");

        if ("XMLHttpRequest".equals(requestedWith)) {
            Message message = new Message();
            message.setCode(403);
            message.setMessage("请登录后操作");
            resp.getWriter().write(JSON.toJSONString(message));
        } else {
            this.saveRequestAndRedirectToLogin(request, response);
        }
        return false;
    }
}

Shiro的配置类里面的配置我就全部放出来了 就看一下与这次配置相关的

@Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        // 设置登录界面URL
        factoryBean.setLoginUrl(loginUrl);
        // 设置未经认证页面的URL
        factoryBean.setUnauthorizedUrl(unauthorizedUrl);
        // 设置登录成功后跳转的URL
        factoryBean.setSuccessUrl(indexUrl);

        HashMap<String, Filter> filter = new HashMap<>();
        filter.put("authc", new GenericFilter());
        filter.put("logout", new LogoutFilter());
        factoryBean.setFilters(filter);

        // 需要认证的加到authc里面
        // 不需要认证的加到anon里面
        HashMap<String, String> filterChain = new HashMap<>();
        filterChain.put("/customize/**", "anon");
        filterChain.put("/plugins/**", "anon");
        filterChain.put("/layuiadmin/**", "anon");
        filterChain.put("/favicon.ico", "anon");
        filterChain.put("/sys/login", "anon");
        filterChain.put("/sys/status", "anon");
        filterChain.put("/sys/captcha", "anon");
        filterChain.put("/device/notice", "anon");
        filterChain.put("/druid/**", "anon");
        filterChain.put("/sys/logout", "logout");

        filterChain.put("/**", "authc");
        factoryBean.setFilterChainDefinitionMap(filterChain);

        return factoryBean;
    }

另外不知道为啥我用jquery的ajax发出的请求都没有X-Requested-With请求头(郁闷...)

我就包装了一下jquery的ajax 手动把这个请求头加上 顺便处理了一下跨域问题

function getJson(url, params, method, success) {
    $.ajax({
        url: host + url,
        data: params,
        method: method,
        async: true,
        dataType: "json",
        xhrFields: {
            withCredentials: true
        },
        crossDomain: true,
        beforeSend: function (xhr) {
            xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
        },
        success: function (data) {
            if (data['code'] == 403) {
                alert(data['message']);
                top.location.href = 'login.html'
            } else {
                if (success) {
                    success(data);
                }
            }
        }, error: function () {
            alert('服务器错误,请联系管理员');
        }
    });
}

这样ajax和网页请求都能正常处理了


注意一个过滤器名只能配一个过滤器 一个资源可以配多个过滤器名 方法为逗号分割 例如

// 定义过滤器
HashMap<String, Filter> filter = new HashMap<>(); filter.put("authc", new GenericFilter()); filter.put("default", new FormAuthenticationFilter()); filter.put("logout", new LogoutFilter()); factoryBean.setFilters(filter);
// 定义过滤链 HashMap
<String, String> filterChain = new HashMap<>(); filterChain.put("/**", "authc,default"); factoryBean.setFilterChainDefinitionMap(filterChain);

DefaultFilterChainManager 会默认添加 org.apache.shiro.web.filter.mgt.DefaultFilter 中声明的拦截器

public enum DefaultFilter { 
    anon(AnonymousFilter.class), 
    authc(FormAuthenticationFilter.class), 
    authcBasic(BasicHttpAuthenticationFilter.class), 
    logout(LogoutFilter.class), 
    noSessionCreation(NoSessionCreationFilter.class), 
    perms(PermissionsAuthorizationFilter.class), 
    port(PortFilter.class), 
    rest(HttpMethodPermissionFilter.class), 
    roles(RolesAuthorizationFilter.class), 
    ssl(SslFilter.class), 
    user(UserFilter.class); 
} 

拦截器说明

默认拦截器名拦截器类说明主要参数
身份验证相关 org.apache.shiro.web.filter.authc
authcFormAuthenticationFilter

基于表单的拦截器

usernameParam: 用户名(username)

passwordParam: 密码(password)

rememberMeParam: 记住密码(remember)

loginUrl: 登录页面("/login.jsp")

successUrl: 登录成功后重定向的页面

failureKeyAttribute: 登录失败后

    错误信息存储(shiroLoginFailure)

authcBasicBasicHttpAuthenticationFilter

Basic HTTP身份验证拦截器

就是浏览器弹出登录窗口的那种

applicationName: 登录框显示的信息(application)
logoutLogoutFilter退出登录拦截器redirectUrl: 退出登录重定向的页面("/")
userUserFilter

用户拦截器

用于验证用户是否通过身份验证

 
anonAnonymousFilter匿名拦截器 无需认证即可访问 
授权相关 org.apache.shiro.web.filter.authz
rolesRolesAuthorizationFilter角色授权拦截器

loginUrl: 登录页面("/login.jsp")

unauthorizedUrl: 未授权跳转的页面

permsPermissionsAuthorizationFilter权限授权拦截器 

未完全实现

1.3.2版本不可用

HostFilter

主机地址拦截器

我调用直接抛异常说暂未实现

authorizedIps: 已授权的ip地址

deniedIPS: 已拒绝的ip地址

portPortFilter端口拦截器

port: 允许通过的端口

如果是非指定端口访问 则重定向到该端口

restHttpMethodPermissionFilter

rest风格拦截器 根据请求方法构建权限字符串

GET=read

POST=create

PUT=update

DELETE=delete

HEAD=read

TEACE=read

OPTIONS=read

MKCOL=create

sslSslFilterSSL拦截器

无参数 只允许https请求通过

如果是非http请求会重定向到443端口

其他
org.apache.shiro.web.filter.session
noSessionCreationNoSessionCreationFilter

不创建会话(Session)拦截器

调用subject.getSession(false)没问题

调用subject.getSession(true)会抛异常

DisabledSessionException

 

节选自《跟我学SHiro》并重新排版,修改了部分内容

免责声明:文章转载自《SpringBoot中Shiro处理ajax请求(重写UserFilter)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【MySQL笔记】mysql来源安装/配置步骤和支持中国gbk/gb2312编码配置关于Oracle表碎片整理下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Ajax异步调用Controller的Return JsonResult生成下拉列表

1 @using System.Web.Optimization; 2 @{ 3 Layout = null; 4 } 5 6 <!DOCTYPE html> 7 8 <html> 9 <head> 10 <meta name="viewport" content="width...

ExtJS 4.2 教程-06:服务器代理(proxy)

在上一节我们介绍了客户端的几种代理,本节的主要内容是介绍如何使用服务器端代理,将重点介绍AjaxProxy,这是我们最常用的代理方式。 Ajax web应用程序开发过程中,与服务器端交互的技术最常用的就是Ajax了。Ajax 是使用Javascript创建一个HttpRequest,采用异步的方式从服务器获取数据。我们先看一个简单的示例: Ext.onR...

使用AJAX技术发送异步请求,HTTP服务端推送 --

使用AJAX技术发送异步请求 什么是AJAX AJAX指一步Javascript和XML(Asynchronous JavaScript And XML),它是一些列技术的组合,简单来说AJAX基于XMLHttpRequest让我们在不重载页面的情况下和服务器进行数据交换。 加上JavaScript和DOM(Document Object Model,文档...

JQuery 之 Ajax 异步和同步浅谈

Ajax 同步和异步的区别 同步是当 JS 代码加载到当前 Ajax 的时候会把页面里所有的代码停止加载,页面出现假死状态;当这个 Ajax 执行完毕后才会继续运行其他代码此时页面假死状态才会解除。反之异步则 Ajax 代码在运行时,其余的 JS 脚本依旧能够运行。 在 Jquery 中可以通过 async 的 true 和 false 设置同步或异步,...

javascript流行框架

1. jQuery – Javascript框架 应用最广泛的JavaScript框架,jQuery插件非常之多,涉及LightBox灯箱插件、日期插件、图表插件等各种类型的插件不计其数,OsChina就收录了1000多款jQuery插件。 2. Dojo Javascript框架 Dojo是一个强大的面向对象JavaScript框架。主要由三大模块组成:C...

解决ajax异步请求数据后swiper不能循环轮播(loop失效)问题、滑动后不能轮播的问题。

问题描述: 1、我使用axios异步请求后台的图片进行渲染后不能实现循环轮播,也就是loop失效,但是静态写死的情况下不会出现这种问题。 2、 分析: swiper的机制是:初始化的时候将swiper-warpperslide类下的最后一个swiper-slide块克隆到第一个的位置,将第一个swiper-slide块克隆岛最后一个的位置,然后自动扫描sw...