过滤器

Shiro还提供了过滤器,可以配置我们的过滤规则,过滤规则对顺序是有要求的,短路优先原则,也就是前面的适配成功之后,就不会再适配后面的规则了。

Shiro是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理等功能,直接查看DefaultFilter类。

路径如下:org.apache.shiro.web.filter.mgt

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);private final Class<? extends Filter> filterClass;private DefaultFilter(Class<? extends Filter> filterClass) {this.filterClass = filterClass;}public Filter newInstance() {return (Filter)ClassUtils.newInstance(this.filterClass);}public Class<? extends Filter> getFilterClass() {return this.filterClass;}public static Map<String, Filter> createInstanceMap(FilterConfig config) {Map<String, Filter> filters = new LinkedHashMap(values().length);DefaultFilter[] var2 = values();int var3 = var2.length;for(int var4 = 0; var4 < var3; ++var4) {DefaultFilter defaultFilter = var2[var4];Filter filter = defaultFilter.newInstance();if (config != null) {try {filter.init(config);} catch (ServletException var9) {String msg = "Unable to correctly init default filter instance of type " + filter.getClass().getName();throw new IllegalStateException(msg, var9);}}filters.put(defaultFilter.name(), filter);}return filters;}
}

AnonymousFilter 匿名拦截器,即不需要登录即可访问;一般用于静态资源过滤;示例/static/**=anon

不需要继承AccessControlFilter,只继承PathMatchingFilter即可

@Override
protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) {// Always return true since we allow access to anyonereturn true;
}

AuthenticationFilter:其主要行为就是认证的过滤,是否通过判断(isAccessAllowed)中进行认证判断。

// 执行登录的公共方法抽取到了这里
protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {// 创建Token时获取用户名密码的行为抽象化AuthenticationToken token = createToken(request, response);if (token == null) {String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +"must be created in order to execute a login attempt.";throw new IllegalStateException(msg);}try {Subject subject = getSubject(request, response);subject.login(token);// 登录成功后的行为return onLoginSuccess(token, subject, request, response);} catch (AuthenticationException e) {// 登录失败后的行为return onLoginFailure(token, e, request, response);}
}protected abstract AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception;protected AuthenticationToken createToken(String username, String password,ServletRequest request, ServletResponse response) {boolean rememberMe = isRememberMe(request);String host = getHost(request);return createToken(username, password, rememberMe, host);
}protected AuthenticationToken createToken(String username, String password,boolean rememberMe, String host) {return new UsernamePasswordToken(username, password, rememberMe, host);
}

FormAuthenticationFilter:其主要行为就是通知拒绝后的处理、登录成功后的行为,登录失败后的行为。基于表单的拦截器;如/**=authc,如果没有登录会跳到相应的登录页面登录

BasicHttpAuthenticationFilter:基于HTTP methods的身份认证拦截器,配置形如:authcBasic[POST,PUT,DELETE,GET],其他的方法名称配置的均不进行过滤形如authcBasic[hello],形如authcBasic[permissive]默认不进行过滤

protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {HttpServletRequest httpRequest = WebUtils.toHttp(request);String httpMethod = httpRequest.getMethod();Set<String> methods = httpMethodsFromOptions((String[])mappedValue);boolean authcRequired = methods.size() == 0;for (String m : methods) {if (httpMethod.toUpperCase(Locale.ENGLISH).equals(m)) { // list of methods is in upper caseauthcRequired = true;break;}}if (authcRequired) {return super.isAccessAllowed(request, response, mappedValue);}else {return true;}
}private Set<String> httpMethodsFromOptions(String[] options) {Set<String> methods = new HashSet<String>();if (options != null) {for (String option : options) {if (!option.equalsIgnoreCase(PERMISSIVE)) {methods.add(option.toUpperCase(Locale.ENGLISH));}}}return methods;
}

LogoutFilter 退出过滤器LogoutFilter自

protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {Subject subject = getSubject(request, response);// Check if POST only logout is enabledif (isPostOnlyLogout()) {// check if the current request's method is a POST, if not redirectif (!WebUtils.toHttp(request).getMethod().toUpperCase(Locale.ENGLISH).equals("POST")) {return onLogoutRequestNotAPost(request, response);}}String redirectUrl = getRedirectUrl(request, response, subject);//try/catch added for SHIRO-298:try {subject.logout();} catch (SessionException ise) {log.debug("Encountered session exception during logout.  This can generally safely be ignored.", ise);}issueRedirect(request, response, redirectUrl);// 重定向后断开过滤链return false;
}

PermissionsAuthorizationFilter 其默认是获取pathConfig中字段并进行比对,一般来说我们需要自定义permissons集合。权限授权拦截器,验证用户是否拥有所有权限;属性和roles一样;示例/user/**=perms["user:create"]

public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {Subject subject = getSubject(request, response);// 该过滤器只有mappedValue不为空的时候才会生效,形如perms[file:edit,file:delete]String[] perms = (String[]) mappedValue;boolean isPermitted = true;if (perms != null && perms.length > 0) {if (perms.length == 1) {if (!subject.isPermitted(perms[0])) {isPermitted = false;}} else {if (!subject.isPermittedAll(perms)) {isPermitted = false;}}}return isPermitted;
}

PortFilter  端口拦截器,主要属性port(80):可以通过的端口;示例/test= port[80],如果用户访问该页面是非80,将自动将请求端口改为80并重定向到该80端口,其他路径/参数等都一样

protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {int requiredPort = toPort(mappedValue);int requestPort = request.getServerPort();return requiredPort == requestPort;
}/** * 默认过滤80端口的请求* /some/path/** = port * 过滤8080端口的请求* /another/path/** = port[8080] **/
protected int toPort(Object mappedValue) {String[] ports = (String[]) mappedValue;if (ports == null || ports.length == 0) {return getPort();}if (ports.length > 1) {throw new ConfigurationException("PortFilter can only be configured with a single port.  You have " +"configured " + ports.length + ": " + StringUtils.toString(ports));}return Integer.parseInt(ports[0]);
}
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {//just redirect to the specified port:int port = toPort(mappedValue);String scheme = getScheme(request.getScheme(), port);StringBuilder sb = new StringBuilder();sb.append(scheme).append("://");sb.append(request.getServerName());if (port != DEFAULT_HTTP_PORT && port != SslFilter.DEFAULT_HTTPS_PORT) {sb.append(":");sb.append(port);}if (request instanceof HttpServletRequest) {sb.append(WebUtils.toHttp(request).getRequestURI());String query = WebUtils.toHttp(request).getQueryString();if (query != null) {sb.append("?").append(query);}}WebUtils.issueRedirect(request, response, sb.toString());return false;
}protected String getScheme(String requestScheme, int port) {if (port == DEFAULT_HTTP_PORT) {return HTTP_SCHEME;// 443端口 : https    } else if (port == SslFilter.DEFAULT_HTTPS_PORT) {return SslFilter.HTTPS_SCHEME;} else {return requestScheme;}
}

Shiro过滤器源码相关推荐

  1. 部署shiro官方源码时,执行maven命令出错

    转载自  部署shiro官方源码时,执行maven命令出错 部署shiro官方源码时,执行maven命令会报下面错误: [INFO] --------------------------------- ...

  2. shiro登陆流程源码详解

    前言 抽取了shiro最基本的登陆流程(web登陆是基于这层开发的). 详解源码 创建一个AuthenticationToken进行登录. SecurityUtils.getSecurityManag ...

  3. Spring Security(四) —— 核心过滤器源码分析

    摘要: 原创出处 https://www.cnkirito.moe/spring-security-4/ 「老徐」欢迎转载,保留摘要,谢谢! 4 过滤器详解 前面的部分,我们关注了Spring Sec ...

  4. Shiro认证源码解析和工作原理

    先行回顾一下使用shiro的步骤: 1. 创建Subject实例对象currUser: 2. 判断当前currUser是否认证过: 3. 如果没有认证过,那么应当调用currUser的login(to ...

  5. JavaWeb三大组件之一——Filter过滤器源码解析(全面手撕Filter源码,需要耐心看完)

    什么是Filter? 本文所说的Filter是JavaWeb中常见常使用的过滤器.Filter的作用是拦截前端发送给后端的请求,一般是用于权限过滤.日志记录.图片转换.加密.数据压缩等操作. 大致流程 ...

  6. mysql布隆过滤器源码_通过实例解析布隆过滤器工作原理及实例

    布隆过滤器 布隆过滤器是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 "一定不存在或者可能存在& ...

  7. mysql布隆过滤器源码_布隆过滤器(Bloom Filter)的原理和实现

    什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...

  8. shiro的源码分析(一)

    (一)//1.获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager Factory factory = new IniSecurityManagerFac ...

  9. shiro官方源码包下载

    http://www.apache.org/dyn/closer.cgi/shiro/1.3.2/shiro-root-1.3.2-source-release.zip,点进这个地址找到蓝色文字的链接 ...

最新文章

  1. mysql 存树 闭包表_关系型数据库树形关系存储-闭包表
  2. OpenCV调用YOLOv4进行目标检测
  3. 使用 Git 生成 SSH Key 并将项目上传到 GitHub
  4. OPENCV数据结构体系和常用函数
  5. 大型网站架构系列:缓存在分布式系统中的应用
  6. 毫米波雷达探测技术,雷达人体存在感应器,实时检测静止存在应用
  7. 中国程序员容易发错音的单词「GitHub 热点速览 v.22.23」
  8. QCC3040---earbud init module
  9. 扒一扒那些叫欧拉的定理们(七)——欧拉线定理的证明
  10. HiveSQL中级进阶常用技巧
  11. 计算机金融专业美国学校排名,美国金融专业都有哪些种类?
  12. Android6.0通讯录权限问题
  13. 敏捷结果30天之第十一天:高效能、慢生活
  14. 解决在EasyUI中使用百度地图出现不居中和坐标图标显示异常的问题(红色代码部分)
  15. 8. Django 模型(二)
  16. 学习管理!!中国历史上最经典的7个智慧案例
  17. 解决 error: called object ‘xxx‘ is not a function or function pointer
  18. SOW/Statement of Work 工作说明书
  19. appium(2)简单的demo、元素定位
  20. Win7启动时黑屏很久才进入桌面的原因

热门文章

  1. 不要在nodejs中阻塞event loop
  2. 在nodejs中创建cluster
  3. Leet Code OJ 283. Move Zeroes [Difficulty: Easy]
  4. Leecode02-两数相加——Leecode热题100道系列
  5. 【三种解法】剑指 Offer 06. 从尾到头打印链表【附完整可运行代码】
  6. Python中get()函数用法【详解】——Python系列学习笔记
  7. NumpyPandas的区别和联系
  8. 计算机网络实验(华为eNSP模拟器)——第五章 单臂路由
  9. ajax基本流程,AJAX基本流程
  10. linux完整面授视频,Linux面授实战