My project is working on the development server. It works in both the following cases:
With the .esapi directory in the source path, so that it ends up in WEB-INF/classes
With the .esapi directory in the lib root, so that it ends up in WEB-INF/lib
However, it doesn't work when deployed to Google (using either of the above 2 strategies).
I get usual messages about not being able to find the ESAPI. properties file when I first try to use ESAPI once deployed to Google.
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: /base/data/home/ap
Not found in SystemResource Directory/resourceDirectory: .esapi/ESAPI.properties
Loading ESAPI.properties via file I/O failed. Exception was: java.io.FileNotFoundException
Attempting to load ESAPI.properties via the classpath.
ESAPI.properties could not be loaded by any means. Fail. Exception was: java.security.Acces
ESAPI does appear to include changes to support AppEngine http://goo.gl/rD8dz
Update
The issue is that line 603 of org.owasp.esapi.reference.DefaultSecurityConfiguration calls ClassLoader.getSystemClassLoader() which is illegal in Google Appengine. This causes the exception above (sorry it's cropped).
There are three ClassLoaders loaded into an array upfront, before the code tries to get the resources.
ClassLoader[] loaders = new ClassLoader[] {
Thread.currentThread().getContextClassLoader(),
ClassLoader.getSystemClassLoader(),
getClass().getClassLoader()
};
String[] classLoaderNames = {
"current thread context class loader",
"system class loader",
"class loader for DefaultSecurityConfiguration class"
};
I've hacked in my own copy of DefaultSecurityConfiguration where I've removed the SystemClassLoader (and corresponding classLoaderName) from the loadConfigurationFromClasspath method.
ClassLoader[] loaders = new ClassLoader[] {
Thread.currentThread().getContextClassLoader(),
getClass().getClassLoader()
};
String[] classLoaderNames = {
"current thread context class loader",
"class loader for DefaultSecurityConfiguration class"
};
Ironically it's because they've made the code easy to read/extent (IMHO) by looping through Classloaders that this approach fails. I'm tempted to submit a patch with an inner class to delay the call to getSystemClassLoader (which you can't do on AppEngine).
It's interesting that this works as it's only possible because the esapi jar is not sealed.
I'd have thought a security library jar should be sealed. Maybe I'm using the wrong one!
Update
I'm using the esapi jar via maven, this has been repackaged and isn't signed. Not ideal, but it's no less secure than the other 40 open source jars I'm getting from maven!
Your solution of overriding the DefaultSecurityConfiguration class with your own implementation is precisely the correct way to address the problem. This is precisely the reason that it is designed this way. There are some other inherent problems with using ESAPI on Google App-Engine tho, primarily with regards to encryption/hashing. This issue has been "partially" resolved according to comments on this thread (http://code.google.com/p/googleappengine/issues/detail?id=1612) but there are still serious limitation on using encryption in GAE.
I just successfully integrated ESAPI 2.1.0 on a Google App Engine Project and I did not even use Maven for it.
Put the ESAPI.properties & validation.properties in the directory [gae-project]/war/ESAPI/.
Thus, the full path of the ESAPI.properties will be
[gae-project]/war/ESAPI/ESAPI.properties
Putting it under the war/ ensures that the files will be uploaded to Google.
Edit your appengine-web.xml, add the following lines inside the <appengine-web-app> root node
...
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties" />
<property name="org.owasp.esapi.resources" value="ESAPI" />
</system-properties>
<static-files>
<exclude path="/ESAPI**properties" />
</static-files>
...
that will allow App Engine to recognize .properties files as project files.
for a more detailed discussion you can also read ESAPI for Google App Engine Integration Tutorial
You can put the files in META-INF/ directory and then change the org.owasp.esapi.resources system property to META-INF/ in appengine-web.xml as follows:
<system-properties>
<property name="org.owasp.esapi.resources" value="META-INF/" />
</system-properties>
Because DefaultSecurityConfiguration seeks configuration files first in the Resource Directory then in the classpath.
The following steps worked for me.
Extract the jar
create one folder .esapi
download ESAPI.properties
create the jar.
Use it,it won't complain about missing properties file anymore.
In our project the file resides in the WEB-INF/classes folder. We do not use a .esapi sub-folder.
Esapi version=2.0.1
Deployed in jboss though.
Related
I have two modules that will use ESAPI with the same properties files (ESAPI and validation.properties).
These modules output to wars that are contained in an ear.
I have the properties files inside one of the war files, where they are found at server start. The other war file seems to work fine and does not complain that it can't find the properties files in the log.
I am using ESAPI to sanitize html and url parameters - I wonder if I even need these property files to be accessible to the second module, or either one since there is no configuration and everything is being done with defaults.
First, let me describe how ESAPI 2.x goes about finding its ESAPI.properties file.
The reference implementation class for ESAPI's SecurityConfiguration interface is
org.owasp.esapi.reference.DefaultSecurityConfiguration
With this default implementation, resources like ESAPI.properties and
Validation.properties can be put in several locations, which are searched in the following order:
1) Inside a directory set with a call to SecurityConfiguration.setResourceDirectory(). E.g.,
ESAPI.securityConfiguration().setResourceDirectory("C:\myApp\resources");
Of course, if you use this technique, it must be done before any other ESAPI calls are made that use ESAPI.properties (which are most of them).
2) Inside the directory defined by the System property "org.owasp.esapi.resources". You can set this on the java command line as follows (for example):
java -Dorg.owasp.esapi.resources="C:\temp\resources" ...
You may have to add this to the start-up script that starts your web server. For example, for Tomcat, in the "catalina" script that starts Tomcat, you can set the JAVA_OPTS variable to the '-D' string above.
3) Inside the
System.getProperty( "user.home" ) + "/.esapi"
directory (supported for backward compatibility) or inside the
System.getProperty( "user.home" ) + "/esapi"
4) The first ".esapi" or "esapi" directory encountered on the classpath. Note this may be complicated by the fact that Java uses multiple class loaders and if you are have multiple applications in a given application server, they may be using different classpaths. For this reason, this option is not generally recommended, but is offered for reasons of backward compatibility with earlier ESAPI 1.4.x versions.
Once ESAPI finds a valid property file (e.g., ESAPI.properties) that it can read, it stops searching for others.
Now, that said, if you want to share a single ESAPI.properties file across all of your .war files, I would recommend going with option #2 and set the System property "org.owasp.esapi.resources" to some common secured directory that both of them can access. Also, you should use a full path name.
The answer was to place the esapi directory containing the properties files in
src/main/application
in one of the modules. This path puts it's contents at the root of the ear.
I'm running ESAPI on a maven project with java 1.8.0_71. I've put ESAPI.properties and validation.properties in
src/main/resources
This worked for me:
Attempting to load ESAPI.properties via the classpath.
SUCCESSFULLY LOADED ESAPI.properties via the CLASSPATH from '/ (root)' using current thread context class loader!
Attempting to load validation.properties via the classpath.
SUCCESSFULLY LOADED validation.properties via the CLASSPATH from '/ (root)' using current thread context class loader!
I'm developing a simple mail sender as Java EE application.
The project structure is shown as follows:
To properly setup email contents, I need to read the *.vm files placed inside the resource folder, that I supposed to have as path classpath:/templates/mail/*.vm (as with Spring)... But my supposition is wrong!
Which is the right path to use?
Should I have to use the META-INF folder? Is this solution more
java-ee-compliant? In that case, where have I to put the META-INF folder inside my project structure?
Update:
I packaged the project as .war, then I putted the files in:
/src/main/webapp/WEB-INF/classes/templates/mail/
Then:
org.apache.velocity.Template t = myVelocityEngine.getTemplate("classpath:/templates/mail/account_to_confirm.vm",
"UTF-8");
Nonetheless, the app returns an error at runtime:
Unable to find resource 'classpath:/templates/mail/account_to_confirm.vm'
What am I doing wrong?
Just to better understand:
Supposing that I'd like to deploy this app as jar (removing the servlet class, of course): in that case, should I have to edit the folder layout in order to still use the same path into the source code?
I think the problem is due to the prefix classpath:: where did you find that you have to use it?
You might find useful understanding how to initialize VelocityEngine reading Loading velocity template inside a jar file and how Configuring Resource Loaders in Velocity.
If you can, use Classloader.getResourceAsStream("templates/mail/*.vm"); or similar getResourceAsURL method.
If not, take a look at where files from resources are placed inside WAR. In your case, the file should be in /WEB-INF/classes/templates/mail .
I am running eclipse on a mac and have my tomcat folder at /Library/WebServer/apache-tomcat.
I am using the tomcat 7 server from within eclipse and configured it to use the original tomcat folder as its working directory.
Problem is that when using the PropertyPlaceholderConfigurer bean in Spring 3.1 and specify the location as "classpath:database.properties", when i start tomcat it will always give me a FileNotFoundException.
I have tried placing the database.properties file in lib,conf and root folder of the tomcat folder.
I am out of options, please help!
EDIT 1
Tried Guido Simone's solution, but i get:
ERROR: org.springframework.web.context.ContextLoader - Context initialization failed
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: /Library/WebServer/apache-tomcat-7.0.32/conf/database.properties (No such file or directory)
So i finally see the full path that spring is looking for the file(which is correct) and the file is physically there. Any other suggestions? And if this is going to work, do other webservers have this catalina.base variable also or is this tomcat specific? Because i kind of need platform independence at a later stage.
I tend to not use the classpath URL for just this reason. I hate having to keep track of exactly how the classpath is configured for various runtime environments. For property files that are likely to be edited (and cannot go into the WAR file) I would recommend something like:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="file:${catalina.base}/conf/database.properties"/>
Now, it's clear that the file is in the conf folder, with all the other configuration stuff.
[update]
catalina.base is definitely Tomcat specific, so the exact XML above would not be portable to other application servers. If you decide to continue with the file: prefix, you would need to do a bit more work and define your own system property to indicate where all your configuration files are ( file:${my.product.conf}/database.properties)
You would need to check the documentation for each app server to figure out how to set this property at startup.
No idea why your are still getting the FileNotFoundException now that the full, absolute path is spelled out. The only thing I can think of is perhaps the file is not really where you think it is :) :) :) Sorry.
I'm using ESAPI for my project, and added the ESAPI configuration directory to src/main/resources so it is copied to my WAR file (I downloaded the WAR from cloudbees, I can see it was put in WEB-INF/classes/esapi/ directory)
Locally, I just point to where the directory is and all works fine, but on cloudbees it just doesn't work for me.
In order to access its properties, ESAPI project tries all kinds of stuff, including checking the org.owasp.esapi.resources system property, so I've added the following code to cloudbees-web.xml:
<sysprop name="org.owasp.esapi.resources" value="WEB-INF/classes/esapi/" />
and I can see that the system property value is found because of the following error in the logs:
Not found in 'org.owasp.esapi.resources' directory or file not readable: /var/genapp/apps/akld3873/WEB-INF/classes/esapi/ESAPI.properties
so it finds the system property (because the path is like I've specified), but when it looks for the actual directory and files in it, I guess the directory is either not there or not readable.
Do I need to move it somewhere else? Inside the WEB-INF directory maybe? Is the setting not right? I've read that others solved similar issues by building a JAR just for this directory, but this doesn't seem like a good solution, there must be a simple setup that will work for cloudbees.
Design for ESAPI lib to require a directory access to configuration is not very flexible.
A general purpose option is to use ServletContext.getRealPath to resolve the absolute filesystem path to this directory and pass it to ESAPI.
Another option is for you to have some init code to copy WEB-INF/classes/esapi content in a temporary directory (using java.io.temp system property to point to the currently configured temp dir for your app) and point ESAPI lib to this path.
Ok so after searching and testing, I finally figured it out.
Cloudbees deploys your web app to the following directory:
staxcat/install/webapp.war/
notice that this is a relative path, with prefix of this path attached it looks something like this:
/var/genapp/apps/xxxxxxxx/staxcat/install/webapp.war/WEB-INF/esapi/ESAPI.properties
so, in order to get ESAPI to work, I had to set the following in cloudbees-web.xml:
<sysprop name="org.owasp.esapi.resources" value="staxcat/install/webapp.war/WEB-INF/esapi" />
this will enable ESAPI to find the directory if in your project it is located under:
src/main/webapp/WEB-INF/esapi
and you should get the following log line:
Found in 'org.owasp.esapi.resources' directory: /var/genapp/apps/xxxxxxxxx/staxcat/install/webapp.war/WEB-INF/esapi/ESAPI.properties
I already searched StackOverflow for "properties inside war", but none of the results worked for my case.
I am using Eclipse Galileo and GlassFish v3 to develop a set of web services. I am using a "dynamic web project" with the following structure
Src
-java_code_pkg_1
-java_code_pkg_2
-com.company.config
--configfile.properties WebContent
-META-INF
-WEB-INF
--log4jProperties
--web.xml
--applicationContext.xml
--app-servlet.xml
I want to access the "configfile.properties" inside one of the source files in "java_code_pkg1". I am using the Spring Framework and this file will be instantiated once the application starts on the server.
I have tried the following with no luck
getResourceAsStream("/com.company.config/configfile.properties");
getResourceAsStream("/com/company/config/configfile.properties");
getResourceAsStream("com/company/config/configfile.properties");
getResourceAsStream("/configfile.properties");
getResourceAsStream("configfile.properties");
getResourceBundle(..) didn't work either.
Is it possible to access a file when it's not under the WEB-INF/classes path? if so then how?
Properties props = new Properties();
props.load(this.getClass().getResourceAsStream("/com/company/config/file.properties"));
works when I'm in debug mode. I can see the values in the debugger, but I get a NullPointerException right after executing the "props.load" line and before going into the light below it.
That's a different issue. At least now I know this is the way to access the config file.
Thank you for your help.
If you are in a war, your classpath "current directory" is "WEB-INF/classes". Simply go up two levels.
getResourceAsStream("../../com/company/config/configfile.properties");
It is horrible but it works. At least, it works under tomcat, jboss and geronimo and It works today.
P.S. Your directory structure is not very clear. Perhaps it is:
getResourceAsStream("../../com.company.config/configfile.properties");
Check the location of the properties file in WAR file.
If it is in WEB-INF/classes directory under com/company/config directory
getResourceAsStream("com/company/config/configfile.properties") should work
or getResourceAsStream(" This should work if the config file is not under WEB-INF/classes directoy
Also try using getClass().getClassLoader().getResourceAsStream.
Are you sure the file is being included in your war file? A lot of times, the war build process will filter out non .class files.
What is the path once it is deployed to the server? It's possible to use Scanner to manually read in the resource. From a java file within a package, creating a new File("../applications/") will get you a file pointed at {glassfish install}\domains\{domain name}\applications. Maybe you could alter that file path to direct you to where you need to go?
Since you are using Spring, then use the Resource support in Spring to inject the properties files directly.
see http://static.springsource.org/spring/docs/3.0.x/reference/resources.html
Even if the class that requires the properties file is not Spring managed, you can still get access to the ApplicationContext and use it to load the resource
resource would be something like, classpath:settings.properties, presuming that your properties file got picked up by your build and dropped in the war file.
You can also inject directly, from the docs:
<property name="template" value="classpath:some/resource/path/myTemplate.txt">