I am working on a Java application for a while. I primarily work on .NET Platform. Although I feel lot of concepts are common between these two platforms but there are few areas where I am finding some issues related to the configuration.
I am working on Authentication and Authorization and thought I would get something similar to Membership APIs of .NET in JAVA. Closest which I got was using j_security_check. I also got to know about JAAS but think it is little too deep for me to dive into.
I have created the user and role tables in the database and now I have to specify the JDBC Realm settings somewhere. I am using Tomcat 7.0. In most places, it's mentioned that I need to specify the realm setting in the server.xml.But wouldn't that apply to all web application deployed on that server since it would become a server level configuration ?.
On a site I even saw a developer mentioning about context.xml but again can't see a standard document that mention about using this XML file for setting JDBC realm
In.NET, We always put Membership settings at the web.config level and not Machine.config.
Totally Confused on this. Looking for some light on this.
Why is Realm setting required in Server.xml and not web.xml
This is not true, you can define it in your webapp as well, but then only in a servletcontainer-specific configuration file, such as /META-INF/context.xml in case of Tomcat. It cannot be definied in /WEB-INF/web.xml because it's specific to the standard Servlet API, not the servletcontainer implementation.
But wouldn't that apply to all web application deployed on that server since it would become a server level configuration ?.
That's correct. This is not recommended if you have no control over the server or if you don't want to publish the realm through other webapps.
On a site I even saw a developer mentioning about context.xml but again can't see a standard document that mention about using this XML file for setting JDBC realm
You can specify it in webapp's /META-INF/context.xml. See also Tomcat's own documentation on the <Context> element:
Defining a context
It is NOT recommended to place <Context> elements directly in the server.xml file. This is because it makes modifying the Context configuration more invasive since the main conf/server.xml file cannot be reloaded without restarting Tomcat.
Individual Context elements may be explicitly defined:
In an individual file at /META-INF/context.xml inside the application files. Optionally (based on the Host's copyXML attribute) this may be copied to $CATALINA_BASE/conf/[enginename]/[hostname]/ and renamed to application's base file name plus a ".xml" extension.
In individual files (with a ".xml" extension) in the $CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The context path and version will be derived from the base name of the file (the file name less the .xml extension). This file will always take precedence over any context.xml file packaged in the web application's META-INF directory.
Inside a Host element in the main conf/server.xml.
(emphasis is not mine, it is already as such in Tomcat's documentation)
Related
I'm working on a Spring MVC project. When I run the application the URL is:
http://localhost:8080/insureYou/login
but I want:
http://localhost:8080/contextroot/insureYou/login
Is there any way of doing it without hardcoding?
In a spring-boot project you can set the context-root by specifying the following property in the application.properties file:
server.servlet.context-path=/yourcontextroot
Without spring-boot, it depends on the webserver and Tomcat offers a number of options.
I would personally opt for a META-INF/context.xml file in your war file containing the necessary information but you can also include the information in the server.xml file or in a ROOT.xml file.
See the following links for further guidance:
How to set the context path of a web application in Tomcat 7.0
https://tomcat.apache.org/tomcat-8.0-doc/config/context.html
https://www.baeldung.com/tomcat-root-application
This type of deployment however sometimes is handled separately, through an Apache server reverse-proxy or through URL rewriting.
I recommend you ascertain whether this type of need is already taken care of by your company's deployment procedures, as you may not need to deal with it at all.
I have a Maven java project, my logging.properties is placed under resources folder. I have configured to print FINE level messages using console logger.
The WAR file generated has the properties file under WEB-INF/classes but, the application when deployed and executed, I can see only INFO level logs.
Should i initialize any LogConfiguration apart from having my logging.properties in the correct path ?
As describe here, you configure loggers in Liberty by something like this in the server.xml:
<logging traceSpecification="*=audit:com.myco.mypackage.*=debug"/>
and see the logging metatype doc to configure other aspects like log file size, number of logs to keep, etc.
Or, as the article mentions, you can use the bootstrap.properties
entries to do the same, e.g. com.ibm.ws.logging.trace.specification.
Though WebSphere also supports java.util.logging APIs, its full infrastructure isn't necessarily configured the same way as say Tomcat, which your app may be patterned after.
If you want to configure different logging behavior for different applications you can have the application Java code use a different Logger name for each, and then configure them differently through the single server.xml config (or also potentially separate the apps out onto different servers).
Dynamically changing the trace settings on a running server can be done simply by editing the server.xml config (as can dynamically configuring almost any aspect of Liberty).
Our Spring Boot application uses log4j2 for logging, but the admins of the server we are going to deploy it to require that:
the logging be fully configurable on their end, i.e., there must be a log4j2.xml file that they can edit to adjust logging formats, files, levels etc., and
The configuration must not be lost or overridden when a new version of the app is deployed (the upload war -> stop tomcat -> delete webapp folder -> start Tomcat) process will be automated.
Ideally, the path to log4j2.xml should be set in the webapps context .xml file — since that's where the DB connection config is. But I can't seem to find a way to make this work. All search results talk about using META-INF/web.xml or application.properties files (not an option, since they get overwritten on deploy), and the only SO question I could find (Spring application without web.xml log4j configuration) did not work for me ("No Configuration was provided") exception on startup.
Set the environment variable logging.config to be the location of your log4j2.xml file.
It's also recommended that you call it log4j2-spring.xml
See https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html
section "Custom log configuration"
I developed a sample web application which will read the data from an external properties file. The properties file is in the source folder in my system and is not included inside the WAR file.
The property file is accessed like this:
Properties prop = new Properties();
//File f1 = new File("Property.properties");
prop.load(getClass().getClassLoader().getResourceAsStream("Property.properties"));
How do I access this property file externally inside the WAR file?
What changes have to be made in the code to read it in the WAR file?
I think the most versatile approach is to define a simple environment entry as described in the section EE.5.4 Simple Environment Entries of Java™ Platform, Enterprise Edition (Java EE) Specification, v5.
From the section (page 68):
A simple environment entry is a configuration parameter used to
customize an application component’s business logic. The environment
entry values may be one of the following Java types: String,
Character, Byte, Short, Integer, Long, Boolean, Double, and Float.
You may also use URL connection factory as described in the section EE.5.6.1.4 Standard Resource Manager Connection Factory Types of the specification.
The Application Component Provider must use the java.net.URL resource
manager connection factory type for obtaining URL connections.
Both require a definition of a resource reference in the deployment descriptor WEB-INF/web.xml of your web application so you can inject the value using #Resource or use JNDI API with java:comp/env as the entry point.
The benefit is that you can change the configuration of your web application without having to recompile the code as well as let you change it using an application server's administrative tools your admins are accustomed with.
In web.xml you define the resource reference.
<resource-ref>
<res-ref-name>propertiesURL</res-ref-name>
<res-type>java.net.URL</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
<resource-ref>
<res-ref-name>propertiesPath</res-ref-name>
<res-type>java.lang.String</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
Then in your code you use the following to access the values:
#Resource
String propertiesPath;
#Resource
URL propertiesURL;
With this you met the requirements of Java EE and you can use propertiesPath or propertiesURL as if they were passed as input parameters to your methods.
Now, it's time to meet expectations of WebSphere Application Server.
What you defined are logical names that need to be mapped to their administered names (an application server knows about and can provide to the application).
In WebSphere Application Server you use WebSphere Binding descriptor WEB-INF/ibm-web-bnd.xml with the following configuration:
<?xml version="1.0" encoding="UTF-8"?>
<web-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_1.xsd"
version="1.1">
<virtual-host name="default_host" />
<resource-ref name="propertyURL" binding-name="propertyURL" />
<resource-ref name="propertyURL" binding-name="propertyURL" />
</web-bnd>
When the application gets deployed WAS allows you to map these mappings to its administered resources. Use the ISC console to define values of the environment entries and map them to the application.
It has became easier with WebSphere Liberty Profile. I described the mechanism as offered by WLP in my article Using #Resource to access JNDI in WebSphere AS 8.5 Liberty Profile.
You have three options:
configure the Websphere to include the directory which contains the property file in the classpath. Don't know how to do it, but I'm sure it is possible, since our application does the same thing
include the property file in the war archive. You probably don't want to do that.
instead using the classloader to load the property file use the file api with an absolute path. I'm not completely sure WAS does allow that, but it is a bad idea anyway, because it makes your application very dependent on things that it really shouldn't care about, such as the installation path of your application.
WebSphere has two folders on the classpath, properties can be loaded from there:
Enterprise Applications > myear > Manage Modules > myjar.jar > Class loader viewer
4 - Extension - com.ibm.ws.bootstrap.ExtClassLoader
file:/projekte/IBM/WebSphere/AppServer-8.5/classes/
file:/projekte/IBM/WebSphere/AppServer-8.5/lib/
Specifically, is it more or less secure having the file on the outside?
This is assuming you put the configuration files in the root directory (of the web server). And that there are only standard restrictions to files applied (no special lock down tools).
Depends on where you put your configuration files in your WAR. In you put it in WEB-INF or META-INF you will not be able route to those files.
/app/WEB-INF/web.xml gives a HTTP 404.
Unless there is some other exploit that would allow someone access to files on the server, I would say its no more secure in the WAR in the right place then outside the WAR file.
Yes it can be secure, although I would not use the root directory of the web server.
Typically a web server is configured to run as its own user (for instance, tomcat on Linux runs as user tomcat). So if the file can only be read by tomcat only the web server can access it.
You can use Context.xml in tomcat's conf directory to either directly inject the settings in the applications context, or add a property there pointing to the file location. That way the location need not be fixed.