Spring Boot Shiro在Web应用中的作用详解

目录
  • 01-Tomcat 中的 Filter 责任链
  • 02-Shiro 中的 filter 链结构
  • 03-shiro-filters 如何与 servlet 中的 filter 关联起来
  • 04-总结

01-Tomcat 中的 Filter 责任链

在前面的文章中,我介绍了如何使用 Apache Shiro 进行安全认证。 其实 Shiro 在 Web 应用中出现的频率更高。 今天我将来分析下,Shiro 是如何应用到 Web 应用中的。

Servlet 规范中定义了 Filter 和 FilterChain 接口,其中都包含一个 doFilter 方法,不过参数有区别:

  • Filter#doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  • FilterChain#doFilter(ServletRequest request, ServletResponse response)

Tomcat 中对 FilterChain 的实现是 org.apache.catalina.core.ApplicationFilterChain,它包括:

  • ApplicationFilterConfig[] filters; 数组,用来保存链中的 Filter,ApplicationFilterConfig 是 Filter 的配置类,通过 ApplicationFilterConfig#getFilter() 可获得对应的 Filter。
  • int pos; 表示链当前位置。
  • int n; 表示 FilterChain 中 Filter 的数量,即 filters 中元素数量。
  • Servlet servlet; 表示应用的 Servlet 实现。

ApplicationFilterChain#doFilter 的实现逻辑:

  • 如果 pos < n,即尚未执行到链表末端,则调用 filters[pos++].getFilter().doFilter(req, res, chain),执行当前 Filter 的 doFilter 方法。
  • 如果 pos >= n,说明链表中所有的 Filter 都执行完毕,则调用 servlet.service(request, response);,执行业务层逻辑。

综上,ApplicationFilterChain 会检查是否有 Filter 需要执行,如果有,则调用 Filter;否则,则将请求交给 Servlet 处理。 Filter 在其 doFilter 方法中,能够拿到当前 Filter 所述的 FilterChain 对象。 在执行完 Filter 后,根据自身逻辑判断是否需要继续将请求传递给 chain 上的后续 Filter 处理,若需要,则调用 chain 的 doFilter 方法。

02-Shiro 中的 filter 链结构

Shiro 中对 FilterChain 的实现是 org.apache.shiro.web.servlet.ProxiedFilterChain,它包括:

  • FilterChain orig; 它是 Tomcat 中的 FilterChain 实例。
  • List<Filter> filters; 是 Shiro 中要执行的安全相关的 Filter(它们也都是实现了 Servlet Filter 的类)。
  • int index; 与 ApplicationFilterChain 中的 pos 异曲同工之妙。

ProxiedFilterChain#doFilter 的实现逻辑:

  • 如果 filters == null || index = filters.size() 说明 Shiro 中安全相关的链已执行完毕,则调用 orig.doFilter(req, res)
  • 否则,说明链中当其 Filter 需要执行,则调用 filters.get(index++).doFilter(request, response, this);

03-shiro-filters 如何与 servlet 中的 filter 关联起来

org.apache.shiro.web.servlet.OncePerRequestFilter 实现了 Servlet 中的 Filter 接口,org.apache.shiro.web.servlet.AbstractShiroFilter 是 OncePerRequestFilter 的基本实现。 因此,AbstractShiroFilter 的派生类都能作为 Filter 添加到 Servlet 的责任链中,即 ApplicationFilterChain 的 filters 中。

Shiro 将 AbstractShiroFilter 的一个实现 org.apache.shiro.spring.web.ShiroFilterFactoryBean.SpringShiroFilter 添加到 filters 中,并命名为 "shiroFilter"。 该类的继承关系如下:

注:org.apache.shiro.web.servlet.OncePerRequestFilter 与 Spring 中的 OncePerRequestFilter 同名,但实现不同。

将 shiroFilter 添加到 filters 中的逻辑在 org.apache.shiro.spring.config.web.autoconfigure.ShiroWebFilterConfiguration 中:

@Bean(name = REGISTRATION_BEAN_NAME)
@ConditionalOnMissingBean(name = REGISTRATION_BEAN_NAME)
protected FilterRegistrationBean<AbstractShiroFilter> filterShiroFilterRegistrationBean() throws Exception {

    FilterRegistrationBean<AbstractShiroFilter> filterRegistrationBean = new FilterRegistrationBean<>();
    filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ERROR);
    filterRegistrationBean.setFilter((AbstractShiroFilter) shiroFilterFactoryBean().getObject());  // SpringShiroFilter 实例
    filterRegistrationBean.setName(FILTER_NAME);    // "shiroFilter"
    filterRegistrationBean.setOrder(1);

    return filterRegistrationBean;
}
复制代码

使用 DEBUG 方式 Shiro Web 应用,也可以佐证上述观点:

Shiro 在 OncePerRequestFilter 中实现了 Filter#doFilter 方法,并在该方法中将过滤器的处理逻辑交由其定义的模板方法 doFilterInternal 来实现。 AbstractShiroFilter 提供了对 doFilterInternal 的基本实现:

将 HttpServletRequest 包装成 ShiroHttpServletRequest

将 HttpServletResponse 包装成 ShiroHttpServletResponse

  • 创建 WebSubject

executeChain(request, response, origChain);,其中 origChain 是 Tomcat 处理请求响应的 ApplicationFilterChain,即 shiroFilter 所在的 chain。

chain = PathMatchingFilterChainResolver#getChain(request, response, origChain); chain 是前面提到的 ProxiedFilterChain 实例。

chain.doFilter(request, response);,相当于将请求交给 shiro-filter 组成的 chain 处理,大体流程与 ApplicationFilterChain 类似。

当请求经过 ApplicationFilterChain 处理,进入到 shiroFilter 时,它的 doFilter 方法(在 OncePerRequestFilter 中)将请求交给 doFilterInternal 方法(在 AbstractShiroFilter 中)处理。 然后会执行与请求路径相关联的 shiro-filter 组成的 chain 对请求、响应进行处理。 下图是 shiro-chain 与 application chain 之间的关系,可以参考下帮助加深理解。

04-总结

今天介绍了 Tomcat 中 Filter 责任链的作用原理以及 Shiro 中实现的安全相关的 Filter 责任链。 并且,还分析了 Shiro 是如何作为一个 Filter 应用到 Web 应用的。 综上,我们了解了一个请求是如何经过层层 Filter 到达 Servlet 中的,也了解了 Shiro 是如何在这个流程中发挥安全认证作用的。 希望以上的内容能对你有所帮助。

以上就是Spring Boot Shiro在Web应用中的作用详解的详细内容,更多关于Spring Boot Shiro Web的资料请关注我们其它相关文章!

(0)

相关推荐

  • Springboot整合ActiveMQ实现消息队列的过程浅析

    目录 pom中导入坐标 书写yml配置 业务层代码 监听器代码 业务层代码 确保你启动了自己电脑的activemq. pom中导入坐标 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> 书写yml配置 spring:  activemq:

  • SpringBoot Bean花式注解方法示例上篇

    目录 1.XML方式声明 2.注解法@Component 3.完全注解式 4.简化注解@Import 1.XML方式声明 这里我举两个例子,一个是自定义的bean,另一个是第三方bean,这样会全面一些. 你还可以定义这个bean的模式,有单例模式和多例模式,prototype代表多例,singleton代表单例. <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://ww

  • Spring Boot在Web应用中基于JdbcRealm安全验证过程

    目录 正文 01-RBAC 基于角色的访问控制 02-Shiro 中基于 JdbcRealm 实现用户认证.授权 03-集成到 Spring Boot Web 应用中 04-总结 正文 在安全领域,Subject 用来指代与系统交互的实体,可以是用户.第三方应用等,它是安全认证框架(例如 Shiro)验证的主题. Principal 是 Subject 具有的属性,例如用户名.身份证号.电话号码.邮箱等任何安全验证过程中关心的要素. Primary principal 指能够唯一区分 Subje

  • SpringBoot Bean花式注解方法示例下篇

    目录 1.容器初始化完成后注入bean 2.导入源的编程式处理 3.bean裁定 拓展 4.最终裁定 1.容器初始化完成后注入bean import lombok.Data; import org.springframework.stereotype.Component; @Component("miao") @Data public class Cat { } 被注入的JavaBean import org.springframework.context.annotation.Con

  • Spring Boot Shiro auto-configure工作流程详解

    目录 01-Shiro 自动配置原理 02-自动配置类 03-Filter 相关的配置类 04-总结 01-Shiro 自动配置原理 Shiro 与 Spring Boot 集成可以通过 shiro-spring-boot-stater 实现,并能完成必要类自动装配. 实现方式是通过 Spring Boot 的自动配置机制,即 WEB-INF/spring.factories 中通过 EnableAutoConfiguration 指定了 6 个自动化配置类: org.springframewo

  • Spring Boot Shiro在Web应用中的作用详解

    目录 01-Tomcat 中的 Filter 责任链 02-Shiro 中的 filter 链结构 03-shiro-filters 如何与 servlet 中的 filter 关联起来 04-总结 01-Tomcat 中的 Filter 责任链 在前面的文章中,我介绍了如何使用 Apache Shiro 进行安全认证. 其实 Shiro 在 Web 应用中出现的频率更高. 今天我将来分析下,Shiro 是如何应用到 Web 应用中的. Servlet 规范中定义了 Filter 和 Filte

  • 使用Spring Boot搭建Java web项目及开发过程图文详解

    一.Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者.SpringMVC是非常伟大的框架,开源,发展迅速.优秀的设计必然会划分.解耦.所以,spring有很多子项目,比如core.context.

  • spring boot集成smart-doc自动生成接口文档详解

    目录 前言 功能特性 1 项目中创建 /src/main/resources/smart-doc.json配置文件 2 配置内容如下(指定文档的输出路径) 3 pom.xml下添加配置 4 运行插件 5 找到存放路径浏览器打开 6 测试结果 前言 smart-doc 是一款同时支持 java restful api 和 Apache Dubbo rpc 接口文档生成的工具,smart-doc 颠覆了传统类似 swagger 这种大量采用注解侵入来生成文档的实现方法. smart-doc 完全基于

  • Spring Boot 2 Thymeleaf服务器端表单验证实现详解

    这篇文章主要介绍了Spring Boot 2 Thymeleaf服务器端表单验证实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 表单验证分为前端验证和服务器端验证. 服务器端验证方面,Java提供了主要用于数据验证的JSR 303规范,而Hibernate Validator实现了JSR 303规范. 项目依赖加入spring-boot-starter-thymeleaf时,默认就会加入Hibernate Validator的依赖. 开

  • Spring boot项目部署到云服务器小白教程详解

    本篇文章主要介绍了Spring boot项目部署到云服务器小白教程详解,分享给大家,具体如下: 测试地址:47.94.154.205:8084 一.Linux下应用Shell通过SSH连接云服务器 //ssh 用户名@公网IP ssh josiah@ip // 输入密码 二.开始搭建SpringBoot的运行环境 1.安装JDK并配置环境变量 1) 打开JDK官网 www.oracle.com 2) 找面最新对应的JDK版本,下载 这里要注意的一个问题是:云服务器下载JDK时一定要在本地去ora

  • Spring Boot加密配置文件特殊内容的示例代码详解

    有时安全不得不考虑,看看新闻泄漏风波事件就知道了我们在用Spring boot进行开发时,经常要配置很多外置参数ftp.数据库连接信息.支付信息等敏感隐私信息,如下 ​ 这不太好,特别是互联网应用,应该用加密的方式比较安全,有点类似一些应用如电商.公安.安检平台.滚动式大屏中奖信息等显示身份证号和手机号都是前几位4109128*********和158*******.那就把图中的明文改造下1. 引入加密包,可选,要是自己实现加解密算法,就不需要引入第三方加解密库 <dependency> &l

  • 基于spring boot 1.5.4 集成 jpa+hibernate+jdbcTemplate(详解)

    1.pom添加依赖 <!-- spring data jpa,会注入tomcat jdbc pool/hibernate等 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <

  • Spring Boot 2.0多数据源配置方法实例详解

    两个数据库实例,一个负责读,一个负责写. datasource-reader: type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://192.168.43.61:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false username: icbc password: icbc driver-class-na

  • spring boot udp或者tcp接收数据的实例详解

    下面用的是 springboot内置integration依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-integration</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot<

  • ssm框架下web项目,web.xml配置文件的作用(详解)

    1. web.xml中配置了CharacterEncodingFilter,配置这个是拦截所有的资源并设置好编号格式. encoding设置成utf-8就相当于request.setCharacterEncoding("UTF-8"); foreEncoding设置成true就相当于response.setCharacterEncoding("UTF-8"); <filter> <filter-name>CharacterEncodingFi

随机推荐