blob: 134ca2e401999bc90c453bb6421ae6990c4827cd [file] [log] [blame]
<!--
Copyright (C) 2009-2013, JoshuaTree. All Rights Reserved.
Licensed to Joshua Tree Software, LLC under New BSD license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
JTS licenses this file to You under the New BSD License
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://joshuatreesoftware.us/
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<body>
<p>
This package is the component that allows security checks to be performed within a
Tomcat runtime environment. The Java Sentry for Tomcat has been split into two packages each contained within
its own jar file.
The Sentry Jars used in Tomcat include:
<ol>
<li>fortressProxyTomcat-[version].jar or </li>
<li>fortressSentry-[version].jar and configuration artifacts</li>
</ol>
The fortressProxyTomcat jar is a thin layer of code that calls the fortressSentry implementation code via standard
Java URLClassloader logic. The Fortress implementation code and configuration artifacts must remain separate from
Tomcat's runtime system classpath. The rationale for separation is it necessary to allow a
predictable and repeatable installation process as throwing non-native jars on any application server
system classpath contains risk due to variability of the runtime environment itself.
To put it simply, it is to keep Fortress code out of the application server's visibility which means
setting up Fortress in Tomcat will work every time if the instructions are followed faithfully.
</p>
<h3>JoshuaTree Fortress Java Sentry Setup Notes for Tomcat Container</h3>
This installation document contains instructions for installing the Fortress Java Sentry for Tomcat. This component works
in Tomcat 4,5,6,7 and JBoss application server environments.
<h4>Guidelines & Tips</h4>
<ul>
<li>In the document that follows, replace <em>[version]</em> with Fortress version label. For example - if Fortress <em>1.0.0</em> release, change fortressProxyTomcat-<em>[version]</em>.jar to fortressProxyTomcat-<em>1.0.0</em>.jar</li>
<li>Restart Tomcat server after any changes to Tomcat config, Fortress config or lib files.</li>
<li>You (usually) do NOT need to restart Tomcat after changes to the LDAP data, i.e. users, passwords, roles.</li>
<li>Steps I - III below are mandatory.</li>
<li>Step IV is optional, for testing purposes.</li>
<li>Common misconfiguration issues related to Fortress, LDAP and Tomcat are located in section V.</li>
<li>Tomcat 7 and beyond uses a different proxy jar. Take special note of this difference in Step III.A.</li>
</ul>
</p>
<ol type="I">
<li>
<h3>Instructions to extract Fortress Java Sentry Package to Target System</h3>
<ol type="A">
<li>Copy fortressSentryDist-<em>[version]</em>.zip to hard drive on target server env.</li>
<li>Extract the zip. The location for archive can vary according to runtime requirements but must be readable by Tomcat process but cannot reside directly on Tomcat's system classpath. The location this package was extracted to will be referred to as <em>FORTRESS_HOME</em> from this point on.</li>
</ol>
</li>
<li>
<h3>Instructions to configure Fortress Java Sentry to use Target System LDAP</h3>
Note: the <b>dist</b> Ant target on this project will use settings contained within the <em>build.properties</em> file contained within the root folder of this component and replace substitution params contained within <em>fortress.properties.src</em> and create new <em>fortress.properties</em> file automatically.<br><br>
<ol type="A">
<li>Edit the FORTRESS_HOME properties file located in $FORTRESS_HOME/conf/fortress.properties. If you did not run Ant <b>dist</b> target you will need to create using fortress.properties.src
<font size="3" color="#000000"><pre>vi /home/user/fortressSentry-1.0.0/conf/fortress.properties</pre></font>
</li>
<li>
Set the LDAP Host name (or IP) and port properties:
<font size="3" color="#000000">
<pre>
host=myldaphostname
port=389
</pre>
</font>
</li>
<li>
Set the LDAP admin creds:
<font size="" color="#000000"><pre>
admin=cn=Manager\,dc=jts\,dc=com
adminPw=secret
</pre>
</font> </li>
<li>
Set the LDAP connection pool info:
<font size="3" color="#000000"><pre>
minUserConn=1
maxUserConn=10
minConn=1
maxConn=10
</pre>
</font> <em>note: the min/max will vary according to anticipated load on your Tomcat server. For busy systems, the max number of
ldap connections may be much higher.</em>
</li>
</ol>
</p>
</li>
<li>
<h3>Instructions to configure Tomcat to use Fortress Java Sentry</h3>
<ol type="A">
<li>Load the Proxy jar onto server classpath (TOMCAT_HOME/lib).<br><br>
<em>if Tomcat 7 and beyond:</em>
<font size="3" color="#000000"><pre>$TOMCAT_HOME/lib>cp $FORTRESS_HOME/lib/fortressProxyTomcat<b>7</b>-[version].jar .</pre></font>
<em>else if Tomcat 4, 5, or 6:</em>
<font size="3" color="#000000"><pre>$TOMCAT_HOME/lib>cp $FORTRESS_HOME/lib/fortressProxyTomcat-[version].jar .</pre></font>
</li>
<em>note: This is the only Fortress binary or configuration artifact that will reside directly on Tomcat's server classpath.</em><br><br>
</p>
<li>Edit the Tomcat server.xml in the $TOMCAT_HOME/conf folder.</li>
<font size="3" color="#000000"><pre>vi $TOMCAT_HOME/conf/server.xml</pre></font>
<li>Comment out existing "Realm" config (if present)
<font size="3" color="#000000"><pre>
&lt;!--Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/--&gt;
</pre></font>
</li>
<li>Add the following to Tomcat's server.xml file:</li>
<font size="3" color="#000000"><pre>&lt;Realm className="us.jts.fortress.realm.tomcat.TcAccessMgrProxy"
debug="0"
resourceName="UserDatabase"
containerType="Tomcat7"
realmClasspath="/home/user/fortressSentry-1.0.0/conf:/home/user/fortressSentry-1.0.0/lib/fortressSentry-1.0.0.jar"
/&gt;</pre></font>
<em>note: <em>/home/user/fortressSentry-1.0.0</em> is an example of where Fortress Java Sentry binaries were extracted. Be sure to enter location of where your Fortress Java Sentry package was extracted on local harddrive as discussed on step I.B above.<br><br>
i.e. /home/user/fortressSentry-1.0.0 or /usr/local/fortressSentry-1.0.0.<br><br>
These packages must remain off the Tomcat server classpath but must be correctly entered in server.xml or Tomcat will fail to initialize.</em><br><br> <li>Save and exit.</li>
<li>Restart Tomcat server.</li>
<li>Verify that Fortress Java Sentry started successfully by viewing following message in catalina.log</li>
<font size="3" color="#000000"><pre>
>/opt/apache-tomcat-6.0.24/bin$ tail -f -n10000 ../logs/catalina.out
...
INFO: us.jts.sentry.tomcat.TcAccessMgrProxy J2EE policy agent initialization successful
If Tomcat 7 and beyond:
INFO: us.jts.sentry.tomcat.Tc7AccessMgrProxy J2EE Tomcat7 policy agent initialization successful
</pre></font>
<em>Note: If you experience problems check out the Common Troubleshooting Tips section at the end of this document.</em><br><br>
</ol>
</p>
</li>
<em>If you made it this far without errors you are now ready to use Fortress enabled security in Tomcat runtime environment.
If you need help understanding how Java EE security works, check out this link:
<br><a href="http://download.oracle.com/javaee/5/tutorial/doc/bnbwk.html">The Java EE 5 Tutorial</a></em><br>
<li>
<h3>Instructions to test Tomcat Security (Optional)</h3>
<em>Note: this section provides instructions for using the Tomcat Manager application
to test Fortress security functionality. This is not necessary if you have your own Java EE security enabled web application to test with.</em><br><br>
<ol type="A">
<li>Enable Tomcat Manager application. note: check the Tomcat documentation on how to do this.</li>
<li>Verify/enable role name. Edit TOMCAT_HOME/webapps/manager/WEB-INF/web.xml</li>
<font size="3" color="#000000"><pre>&lt;!-- Security roles referenced by this web application --/&gt;
&lt;security-role/&gt;
&lt;description/&gt;
The role that is required to log in to the Manager Application
&lt;/description/&gt;
&lt;role-name/&gt;manager&lt;/role-name/&gt;
&lt;/security-role/&gt;
</pre></font>
<li>Add Role to access Tomcat Manager application</li><pre>
<em>Note: If Fortress <b>init-slapd</b> Ant task was run this data will already be loaded into the directory using the
<b>FortressDemoUsers.xml</b> load script.</em>
<em>If Tomcat 7 and beyond:</em>
Add Role named <b>manager-gui</b>
<em>else if Tomcat 6 and before:</em>
Add Role named <b>manager</b>
</pre>
<li>Add User named <strong>tcmanager</strong>: (or whatever you want to name it)</li>
<li>Assign Test User <strong>tcmanager</strong> Role <strong>manager</strong>, (if Tomcat 7 this role is <strong>manager-gui</strong>)</li>
<li>Test logon onto the Tomcat Manager app.</li>
<li>Enter URL to manager web app:</li>
<font size="3" color="#000000"><pre>http://localhost:8080/manager/html</pre></font>
<li>Enter creds (tcmanager, password) into basic logon form</li>
<li>Verify authentication/authorization success to web app.</li>
</ol>
</p>
</li>
<li>
<h3>Common Troubleshooting Tips</h3>
<ol type="A">
<li>Server can't find config files (realmClasspath="/fortressSentry-1.0.0/conf/")
<h4>Error</h4>
<font size="3" color="#000000"> <pre>
Jul 15, 2011 8:21:16 PM Tc7AccessMgrProxy initialize
INFO: Tc7AccessMgrProxy.initialize - instantiate policy agent name: TcAccessMgrImpl
2011-07-15 20:21:17,053 (FATAL) us.jts.fortress.configuration.Config static init: Error, null configuration file: fortress.properties
Jul 15, 2011 8:21:17 PM Tc7AccessMgrProxy startInternal
SEVERE: Tc7AccessMgrProxy.startInternal caught Throwable=java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
at J2eePolicyMgrFactory.<clinit>(J2eePolicyMgrFactory.java:32)
at TcAccessMgrImpl.<init>(TcAccessMgrImpl.java:35)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at Tc7AccessMgrProxy.initialize(Tc7AccessMgrProxy.java:112)
at Tc7AccessMgrProxy.startInternal(Tc7AccessMgrProxy.java:236)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1026)
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:291)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:727)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
at org.apache.catalina.startup.Catalina.start(Catalina.java:620)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:303)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:431)
Caused by: java.lang.RuntimeException: us.jts.fortress.configuration.Config static init: Error, null configuration file: fortress.properties
at us.jts.fortress.configuration.Config.<clinit>(Config.java:51)
... 25 more
</pre>
</font> <h4>Corrective Action</h4>
<pre>
<em>Ensure step III.D points to Fortress sentry configuration folder.</em>
</pre>
</li>
<li>Server can't find proxy jar (Realm className="TcAccessMgrProxy")
<h4>Error</h4>
<font size="3" color="#000000"> <pre>
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/i386/server:/usr/lib/jvm/java-6-sun-1.6.0.22/jre/lib/i386:/usr/lib/jvm/java-6-sun-1.6.0.22/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib
Apr 22, 2011 10:24:04 PM org.apache.tomcat.util.digester.Digester startElement
SEVERE: Begin event threw exception
java.lang.ClassNotFoundException: us.jts.sentry.tomcat.TcAccessMgrProxy
</pre>
</font>
<h4>Corrective Action</h4>
<pre>
<em>Ensure step III.A copied the Fortress sentry proxy jar to TOMCAT_HOME/lib folder.</em>
</pre>
</li>
<li>Server can't find binaries (realmClasspath="...FORTRESS_HOME/lib/fortressSentry-[version].jar")
<h4>Error</h4>
<font size="3" color="#000000"> <pre>
Apr 22, 2011 10:22:25 PM us.jts.sentry.tomcat.TcAccessMgrProxy initialize
SEVERE: Fortress Tomcat Realm.initialize java.lang.ClassNotFoundException=java.lang.ClassNotFoundException: TcAccessMgrImpl
Apr 22, 2011 10:22:25 PM us.jts.sentry.tomcat.TcAccessMgrProxy start
SEVERE: Fortress Tomcat Realm.start caught Exception=java.lang.RuntimeException: Fortress Tomcat Realm.initialize java.lang.ClassNotFoundException=java.lang.ClassNotFoundException: TcAccessMgrImpl
java.lang.RuntimeException: Fortress Tomcat Realm.initialize java.lang.ClassNotFoundException=java.lang.ClassNotFoundException: TcAccessMgrImpl
at us.jts.sentry.tomcat.TcAccessMgrProxy.initialize(TcAccessMgrProxy.java:118)
</pre>
</font>
<h4>Corrective Action</h4>
<pre>
<em>Ensure step III.D configuration points fortressSentry jar,
i.e. FORTRESS_HOME/lib/fortressProxyTomcat[version].jar.</em>
</pre>
</li>
<li>Incompatible Tomcat Proxy jar loaded for Tomcat 7 and beyond
The Tomcat sentry base class changed between Tomcat version's 6 and 7. If you are running Tomcat7 and see error that looks like this:
<h4>Error</h4>
<font size="3" color="#000000"> <pre>
Jun 4, 2011 3:01:41 PM org.apache.tomcat.util.digester.Digester startElement
SEVERE: Begin event threw error
java.lang.VerifyError: class us.jts.sentry.tomcat.TcAccessMgrProxy overrides final method start.()V
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at org.apache.tomcat.util.digester.ObjectCreateRule.begin(ObjectCreateRule.java:144)
at org.apache.tomcat.util.digester.Digester.startElement(Digester.java:1282)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:179)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1343)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2755)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1543)
at org.apache.catalina.startup.Catalina.load(Catalina.java:554)
at org.apache.catalina.startup.Catalina.load(Catalina.java:595)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:262)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:430)
</pre>
</font>
<h4>Corrective Action</h4>
<pre>
<em>You have the wrong Tomcat Proxy jar on the server's classpath.
You need to get the proxy jar that is compatible with Tomcat version 7 and beyond.
Ensure step III.A configuration uses fortressProxyTomcat7-[version].jar,
i.e. FORTRESS_HOME/lib/fortressProxyTomcat7-[version].jar.</em>
</pre>
</li>
<li>Incompatible Tomcat Proxy jar loaded for Tomcat 6 and before
The Tomcat sentry base class changed between Tomcat version's 6 and 7. If you are running Tomcat 4, 5 or 6 and see error that looks like this
<h4>Error</h4>
<font size="3" color="#000000"> <pre>
SEVERE: An exception or error occurred in the container during the request processing
java.lang.RuntimeException: us.jts.sentry.tomcat.Tc7AccessMgrProxyauthenticate detected Fortress Tomcat7 Realm not initialized correctly. Check your Fortress Realm configuration
at us.jts.sentry.tomcat.Tc7AccessMgrProxy.authenticate(Tc7AccessMgrProxy.java:161)
at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:259)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:449)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)
</pre>
</font>
<h4>Corrective Action</h4>
<pre>
<em>You have the wrong Tomcat Proxy jar on the server's classpath.
You need to get the proxy jar that is compatible with Tomcat version 6 and before:
Ensure step III.A configuration uses fortressProxyTomcat-[version].jar,
i.e. FORTRESS_HOME/lib/fortressProxyTomcat-[version].jar.</em>
</pre>
</li>
</ol>
</p>
</li>
</ol>
</body>