PSI-Probe is an extended Tomcat manager. This post outlines how to place it behind CAS and specify permissions based on an LDAP attribute. The method outlined in this post has been adapted from documentation from Jasig on Tomcat Container Authentication, written by Marvin S. Addison.
Although the current stable build of PSI-Probe cannot be placed behind CAS (the role names are hard coded into the program), the current source code allows for flexible role names.
Check out the source code (SVN). The command can be found on psi-probe’s website. A readme is included in the source, follow the instructions found there (an Oracle driver must be imported into Maven to properly build psi-probe). The readme explains how to package the source into a .war which can then be deployed on the server.
The process of modifying the configuration files to support CAS authentication can either be done in the source code before building the .war or afterward on the server (by modifying the unpacked files). My preference, for the sake of flexibility, is to put in a place holder for the attribute names (role names) before building the .war, then use a script to string replace the placeholder with the attribute name within the modified configuration files on the server.
Before modifying any configurations, you must obtain several .jar files and place them in your $TOMCAT_HOME/lib directory.
Found in CAS-Client under modules (can be downloaded from Jasig) :
Can be obtained from Apache and OpenSAML
The first file that must me modified is the context.xml. It can be found at the following locations:
Source: $SOURCE_DIR/web/src/main/conf/META-INF/context.xml Server: $TOMCAT_HOME/conf/Catalina/localhost/probe.xml
The file should read:
<?xml version="1.0" encoding="UTF-8"?> <Context path="/probe" privileged="true" > <!-- The following configuration uses the SAML 1.1 protocol and role data provided by the assertion to enable dynamic server-driven role data. The attribute used for role data is "memberOf". --> <Realm className="org.jasig.cas.client.tomcat.v6.AssertionCasRealm" roleAttributeName="memberOf" /> <Valve className="org.jasig.cas.client.tomcat.v6.Saml11Authenticator" encoding="UTF-8" casServerLoginUrl="https://login.example.com/cas/login" casServerUrlPrefix="https://login.example.com/cas/" serverName="your.server.example.com" /> <!-- Single sign-out support --> <Valve className="org.jasig.cas.client.tomcat.v6.SingleSignOutValve" artifactParameterName="SAMLart" /> </Context>
The attribute does not have to be memberOf, any attribute name can be specified here.
Next the roles have to be specified in the application. This is done in spring-probe-security.xml
Source: $SOURCE_DIR/web/src/main/webapp/WEB-INF/spring-probe-security.xml Server: $TOMCAT_HOME/webapps/probe/WEB-INF/spring-probe-security.xml
The following section should be modified to read as outlined below. ROLE_ must be followed by the name of the attribute or entitlement you set up to grants permission.
<sec:filter-invocation-definition-source> <sec:intercept-url pattern="/adm/**" access="ROLE_ATTRIBUTE"/> <sec:intercept-url pattern="/sql/**,/adm/restartvm.ajax" access="ROLE_ATTRIBUTE"/> <sec:intercept-url pattern="/app/**" access="ROLE_ATTRIBUTE"/> <sec:intercept-url pattern="/**" access="ROLE_ATTRIBUTE"/> </sec:filter-invocation-definition-source>
Finally, the web.xml must be modified to properly filter access.
Source: $SOURCE_DIR/web/src/main/webapp/WEB-INF/web.xml Server: $TOMCAT_HOME/webapps/probe/WEB-INF/web.xml
<context-param> <description>Role that can view session attribute values</description> <param-name>attribute.value.roles</param-name> <param-value>ROLE_ATTRIBUTE</param-value> </context-param>
<auth-constraint> <role-name>$attribute_name</role-name> </auth-constraint>
<security-role> <role-name>$attribute_name</role-name> </security-role>
You will notice that there are several entries for ROLE and security-role within web.xml. These provide levels of access, which can be specified (you will have to modify spring-probe-security.xml to reflect permission levels set in web.xml). If you don’t deem them necessary, you can remove them completely from web.xml and simply leave a single entry (as shown above).