近期项目中需要使用到组件包ESAPI(ESAPI是owasp提供的一套API级别的web应用解决方案),其官方网站为:https://www.owasp.org/,
有兴趣的小伙伴可以了解一下。此处不是本文重点,本文重点记录一下使用此组件时遇到的资源加载问题。

引入jar

<!-- https://mvnrepository.com/artifact/org.owasp.esapi/esapi -->
<dependency><groupId>org.owasp.esapi</groupId><artifactId>esapi</artifactId><version>2.1.0.1</version>
</dependency>

问题

在使用此API时,需要引入三个资源文件,分别是ESAPI.propertiesvalidation.propertiesantisamy-esapi.xml

so easy,直接放入项目resources目录中的esapi下,单元测试跑起来

    @Testpublic void esapiTest() {String input = "<p>test <b>this</b> <script>alert(document.cookie)</script><i>right</i> now</p>";try {String safe2 = ESAPI.validator().getValidSafeHTML("get safe html", input, Integer.MAX_VALUE, true);logger.info("getValidSafeHTML:{}", safe2);} catch (ValidationException e) {logger.error("error", e);}}

运行结果

System property [org.owasp.esapi.opsteam] is not set
Attempting to load ESAPI.properties via file I/O.
Attempting to load ESAPI.properties as resource file via file I/O.
Not found in 'org.owasp.esapi.resources' directory or file not readable: E:\intelliGit\Tiffany\XSS\ESAPI.properties
Found in SystemResource Directory/resourceDirectory: E:\intelliGit\Tiffany\XSS\target\classes\esapi\ESAPI.properties
Loaded 'ESAPI.properties' properties file
SecurityConfiguration for Validator.ConfigurationFile.MultiValued not found in ESAPI.properties. Using default: false
Attempting to load validation.properties via file I/O.
Attempting to load validation.properties as resource file via file I/O.
Not found in 'org.owasp.esapi.resources' directory or file not readable: E:\intelliGit\Tiffany\XSS\validation.properties
Found in SystemResource Directory/resourceDirectory: E:\intelliGit\Tiffany\XSS\target\classes\esapi\validation.properties
Loaded 'validation.properties' properties file
System property [org.owasp.esapi.devteam] is not set
Attempting to load antisamy-esapi.xml as resource file via file I/O.
Not found in 'org.owasp.esapi.resources' directory or file not readable: E:\intelliGit\Tiffany\XSS\antisamy-esapi.xml
Found in SystemResource Directory/resourceDirectory: E:\intelliGit\Tiffany\XSS\target\classes\esapi\antisamy-esapi.xml
十一月 08, 2018 10:39:59 上午 org.owasp.esapi.reference.JavaLogFactory$JavaLogger log2018-11-08 10:39:59 [main] INFO com.tiffany.xss.EsapiTest  - getValidSafeHTML:<p>test <b>this</b> <i>right</i> now</p>

ok, 大功告成,引入web项目,jetty启动,访问结果

Not found in 'org.owasp.esapi.resources' directory or file not readable:
Not found in SystemResource Directory/resourceDirectory: .esapi\ESAPI.properties
Not found in 'user.home' (C:\Users\wangxinguo) directory: C:\Users\wangxinguo\esapi\ESAPI.propertiesNot found in 'org.owasp.esapi.resources' directory or file not readable:
Not found in SystemResource Directory/resourceDirectory: .esapi\validation.properties
Not found in 'user.home' (C:\Users\wangxinguo) directory: C:\Users\wangxinguo\esapi\validation.propertiesNot found in 'org.owasp.esapi.resources' directory or file not readable:
Not found in SystemResource Directory/resourceDirectory: .esapi\antisamy-esapi.xml
Not found in 'user.home' (C:\Users\wangxinguo) directory: C:\Users\wangxinguo\esapi\antisamy-esapi.xmlCaused by: org.owasp.esapi.errors.ConfigurationException: Couldn't find antisamy-esapi.xmlat org.owasp.esapi.reference.validation.HTMLValidationRule.<clinit>(HTMLValidationRule.java:55)... 33 more
Caused by: java.io.FileNotFoundExceptionat org.owasp.esapi.reference.DefaultSecurityConfiguration.getResourceStream(DefaultSecurityConfiguration.java:532)at org.owasp.esapi.reference.validation.HTMLValidationRule.<clinit>(HTMLValidationRule.java:53)... 33 more

什么鬼?资源文件找不到??不是已经放在classpath中了么?

  • 难道没打包?

    直接查看打包war文件,
    /webapp/WEB-INF/classes/esapi三个文件的确存在呀,再说单元测试也可以通过呀,这不开玩笑么?

  • 难道jetty容器解压有毒?(不合理的怀疑)

    直接上服务器jetty的work目录中,/webapp/WEB-INF/classes/esapi三个文件也的确存在

没办法,再看异常日志

Not found in 'org.owasp.esapi.resources' directory or file not readable

看到可以通过指定jvm启动环境变量来指定资源文件的路径

-Dorg.owasp.esapi.resources={path}

重新启动,发现文件解决

但是这个不是我想要的结果,我是想让程序直接加载我classpath路径下的资源文件,
这样不用在容器启动的时候还要强制声明resource path

那就直接看源码呗,直接debug走一波
org.owasp.esapi.reference.DefaultSecurityConfigurationgetResourceFile方法


public File getResourceFile(String filename) {logSpecial("Attempting to load " + filename + " as resource file via file I/O.");if (filename == null) {logSpecial("Failed to load properties via FileIO. Filename is null.");return null; // not found.}File f = null;// first, allow command line overrides. -Dorg.owasp.esapi.resources// directoryf = new File(customDirectory, filename);if (customDirectory != null && f.canRead()) {logSpecial("Found in 'org.owasp.esapi.resources' directory: " + f.getAbsolutePath());return f;} else {logSpecial("Not found in 'org.owasp.esapi.resources' directory or file not readable: " + f.getAbsolutePath());}// if not found, then try the programmatically set resource directory// (this defaults to SystemResource directory/resourceFileURL fileUrl = ClassLoader.getSystemResource(resourceDirectory + "/" + filename);if ( fileUrl == null ) {fileUrl = ClassLoader.getSystemResource("esapi/" + filename);}if (fileUrl != null) {String fileLocation = fileUrl.getFile();f = new File(fileLocation);if (f.exists()) {logSpecial("Found in SystemResource Directory/resourceDirectory: " + f.getAbsolutePath());return f;} else {logSpecial("Not found in SystemResource Directory/resourceDirectory (this should never happen): " + f.getAbsolutePath());}} else {logSpecial("Not found in SystemResource Directory/resourceDirectory: " + resourceDirectory + File.separator + filename);}// If not found, then try immediately under user's home directory first in//        userHome + "/.esapi"     and secondly under//        userHome + "/esapi"// We look in that order because of backward compatibility issues.String homeDir = userHome;if ( homeDir == null ) {homeDir = "";   // Without this,    homeDir + "/.esapi"  would produce// the string      "null/.esapi"     which surely is not intended.}// First look under ".esapi" (for reasons of backward compatibility).f = new File(homeDir + "/.esapi", filename);if ( f.canRead() ) {logSpecial("[Compatibility] Found in 'user.home' directory: " + f.getAbsolutePath());return f;} else {// Didn't find it under old directory ".esapi" so now look under the "esapi" directory.f = new File(homeDir + "/esapi", filename);if ( f.canRead() ) {logSpecial("Found in 'user.home' directory: " + f.getAbsolutePath());return f;} else {logSpecial("Not found in 'user.home' (" + homeDir + ") directory: " + f.getAbsolutePath());}}// return null if not foundreturn null;}

源码流程也很简单

  • 首先通过 -Dorg.owasp.esapi.resources指定路径获取,如果存在,直接返回

  • 上面过程获取不到,通过ClassLoader.getSystemResource("esapi/" + filename);来获取,如果存在,直接返回

  • classloader也获取不到,查找userHome中是否存在

调试分析

  • 单元测试启动

ClassLoader.getSystemClassLoader()

Thread.currentThread().getContextClassLoader()

使用的都是jvm的ClassLoader,并且资源文件都可以找到

  • jetty容器启动

ClassLoader.getSystemClassLoader()

Thread.currentThread().getContextClassLoader()

发现当前线程的classloader是通过jetty容器WebAppClassLoader获取,而并非jvm的classloader

至于此次问题怎么发现,是源于之前隐约记得在看 JAVA类加载器
有提到过双亲模式的破坏,Tomcat的WebappClassLoader 就会先加载自己的Class,找不到再委托parent

当时看到这里的时候也是大概看了一下,也没深入去理解,只在脑海中停留了一下,

借此在网上找到有位大神的讲解正符合此情景,于是就仔细去拜读了一下,加深容器类加载器的理解,避免以后再出现此类诡异的问题
Jetty源码阅读—Jetty的类加载器WebAppClassLoader

另外还有一位小伙伴的分享也是不错的,故此处记录一下关于getSystemResource, getResource 的总结

关于ESAPI获取资源文件问题相关推荐

  1. java获取资源文件的各种方法

    1.在test环境中获取xml: @Test     public void testFindUserById() throws Exception{ String resource = " ...

  2. java资源文件路径_Java 中获取资源(文件)的路径问题总结

    Java 中获取资源(文件)的路径问题总结 首先,Java 中获取资源大体上可分为两种方式,基于 文件系统的 和 基于classpath的. 1. 基于文件系统的相对简单. 比如 构造一个File f ...

  3. java 获取文件版本号_Java 获取资源文件路径

    1 问题描述 通过源码运行时,一般使用如下方式读取资源文件: String str = "1.jpg"; 资源文件与源码文件放在同一目录下,或者拥有同一父级目录: String s ...

  4. java get image获取根路径_Java 获取资源文件路径

    1 问题描述 通过源码运行时,一般使用如下方式读取资源文件: String str = "1.jpg"; 资源文件与源码文件放在同一目录下,或者拥有同一父级目录: String s ...

  5. springboot jar包运行中获取资源文件

    1. 今天晚上写了一个程序,基于Spring boot的一个小网站,发现使用FileUtils.class.getResource(path)来获取jar包中的资源文件并不能成功,其路径很奇怪 fil ...

  6. getresourceasstream 路径_Java 获取资源文件路径

    1 问题描述 通过源码运行时,一般使用如下方式读取资源文件: String str = "1.jpg"; 资源文件与源码文件放在同一目录下,或者拥有同一父级目录: String s ...

  7. Java中获取资源文件路径

    Java路径 Java中使用的路径,分为两种:绝对路径和相对路径.具体而言,又分为四种: 一.URI形式的绝对资源路径 如:file:/D:/java/eclipse32/workspace/jbpm ...

  8. iOS基础:获取资源文件的方法

    bundle是一个目录,其中包含了程序会使用到的资源.这些资源包含了如图像,声音,编译好的代码,nib文件(用户也会把bundle称为plug-in).对应bundle,cocoa提供了类NSBund ...

  9. Android中获取资源文件的几种方法

    1.通过String获取其在R.drawable中的int try{ Field field=R.drawable.class.getField("icon"); int i= f ...

  10. java文件流null_JAVA 获取资源文件对象为NULL

    今天,写一个添加背景音乐的方法时,在导入当前文件夹下的音乐时中始终出现,以下的异常,Exception in thread "main" java.lang.NullPointer ...

最新文章

  1. GridView和DetailsView在同一页与不同页两种情况的联动
  2. ext2.2打造全新功能grid系列--仅仅动态生成GridPanel
  3. 交换机是如何对数据包打标签去标签的_如何使用PC抓带vlan标签的数据包?王海军老师告诉你...
  4. 剑指offer 面试31题
  5. 实践 config drive - 每天5分钟玩转 OpenStack(170)
  6. 修改oracle数据连接数据库,修改Oracle数据库的连接数
  7. Kafka解析之失效副本
  8. Qucs 产生大文件的一个bug
  9. 画箱线图_箱线图的N种画法
  10. 低代码发展专访系列之六:低代码平台能解决业务重构的问题么?
  11. 2021计算机专业考408的学校,2021考研:计算机考研408是什么?统考学校有哪些?...
  12. java 实例 登录用户 equals的用法
  13. 老罗直播原定的12台半价哈弗F7仅售4台就下架?官方回应来了
  14. SAP License:关于未分摊差异的几种处理办法
  15. 将汉语转换成拼音,实现拼音和中文双重登录
  16. 没有人脉如何靠内推进大厂?内推真的那么神吗?带你搞透内推到底是什么
  17. 蓝桥杯--算法提高 字符串跳步(java)
  18. 老李分享:六度分隔理论
  19. opencv将图像处理之后显示在label上(Mat转化为qimage)转换之后label显示全黑
  20. 基于javaweb的自习室图书馆座位预约管理系统(java+ssm+jsp+easyui+mysql)

热门文章

  1. 【机器学习|数学基础】Mathematics for Machine Learning系列之矩阵理论(15):矩阵的范数
  2. 阿里再“牵手”中国邮政 民营快递或共享资源?
  3. python根据服务器sn号查询DELL服务器型号、出厂时间、过保时间
  4. android bochs,通过 Bochs 让高性能的 Android 手机流畅运行 Windows 虚拟机
  5. smartsvn破解版
  6. 谢晶:webpower中国区正在向“多渠道智能化营销”全面转型
  7. 常用审计计算机软件,审计软件
  8. html修改修改头像业务,修改头像.html
  9. 学信网如何通过证件编码查学历
  10. hmcl启动器java下载_HMCL启动器|Hello Minecraft! Launcher 3.2 —— Win/Mac苹果系统/Ubuntu|2亿次使用...