Child pages
  • Adding ESG security to a TDS server
Skip to end of metadata
Go to start of metadata

The Thredds Data Server (TDS) [1] is one of the most common servers that can be deployed on an ESG Data Node to serve data through many possible APIs (OpenDAP, NetCDF, WMS, WCS etc.). When deployed as part of the ESG federation, a TDS must be configured to conform to the ESG security architecture through the steps outlined below. Note that these instructions assume that an ESG Openid Relying Party (ORP) has been istalled in a Tomcat container accessible at the same domain name as the TDS - preferably the same Tomcat container that is hosting the TDS.

Security Configuration
  1. The following jar files must be installed in the <TDS INSTALL>/webapps/thredds/WEB-INF/lib directory:
    1. esg-datanode.jar (containing the security access filters).
    2. esg-saml.jar (containing ESG-specific SAML support)
    3. opensaml-2.2.3.jar
      1. openws-1.2.2.jar
      2. xmltooling-1.2.1.jar
    4. XSGroupRole.jar
  2. Generate a trustore file (in Java keystore format) that contains the credentials used by the ORP to sign the SAML authentication assertions. This is necessary because the TDS access control filters will have to validate the assertion retrieved from the authentication cookie. Store the file in a well know location that will be referenced in the web.xml (see below).
  3. Edit the file <TDS INSTALL>/thredds/webapps/WEB-INF/web.xml and insert the XML snippet that configures the ESG access control filters to intercepts all requests sent to the TDS (see example below). You must configure the filter parameters to values that are specific to your system, specifically:
    1. AuthenticationFilter:
      1. openidRelyingPartyUrl: insert the URL of the previously installed ESG ORP, for example openidRelyingPartyUrl=https://tds.prototype.ucar.edu:8443/OpenidRelyingParty/home.htm
      2. When securing a non-TDS server, replace the value of the parameter policyServerClass with the class name of the specific implementation of PolicyServerFilterCollaborator.java that is specific to that particular server. When securing a TDS, use policyServerClass=esg.datanode.security.app.tds.TDSPolicyService
      3. Map the authentication filter to intercept all requests for netcdf files: <url-pattern>*.nc</url-pattern>
    2. AuthorizationFilter:
      1. authorizationServiceUrl: the endpoint of the Gateway SAML Authorization Service that is invoked to establish authorization, for example: https://esg.prototype.ucar.edu/saml/soap/secure/authorizationService.htm
      2. truststorePath: insert the path on the local filesystem of the trustore file containing the ORP credentials. For example trustoreFile=/usr/local/java/jre/lib/security/jssecacerts
      3. trustorePassword: the password used to open the trustore file
      4. Map the authorization filter to intercept all requests for netcdf files: <url-pattern>*.nc</url-pattern>
  4. Still in the file <TDS INSTALL>/thredds/webapps/WEB-INF/web.xml, find the configuration for the RestrictedDataset servlet and change the implementation of the Authorizer from the default value: thredds.servlet.restrict.TomcatAuthorizer to the ESG-specific TDS authorizer: esg.datanode.security.app.tds.TDSAuthorizer
  5. Edit the file <TDS INSTALL>/thredds/webapps/WEB-INF/log4j.xml and insert the XML snippet that defines the proper level of logging for the esg and eske packages (see example below):
    1. INFO will currently produce almost no logging
    2. DEBUG will produce very detailed logging for each HTTP request. Additionally, if both the TDS and the associated ORP are running in debug mode, an initialization test will be executed when the two application containers are started up, which checks that SAML assertions signed by the ORP can be validated by the TDS, so that possible misconfiguration problems between the ORP keystore and  the TDS trustore can be identified early.
  6. Finally, just like when installing the ORP, the Tomcat contained must be configured to use the XML libraries needed by SAML. Edit your Tomcat startup script and add an enviromental variable that points to a directory containing up-to-date jars for SAML processing:
    1. -Djava.endorsed.dirs=$CATALINA_HOME/endorsed
    2. Restart Tomcat

Example of filter configuration in web.xml:

    <!-- Authentication Filter -->
    <filter>
        <filter-name>authenticationFilter</filter-name>
        <filter-class>esg.datanode.security.app.AuthenticationFilter</filter-class>
        <init-param>
            <param-name>policyServiceClass</param-name>
            <param-value>esg.datanode.security.app.tds.TDSPolicyService</param-value>
        </init-param>
        <init-param>
            <param-name>openidRelyingPartyUrl</param-name>
            <param-value>https://tds.prototype.ucar.edu/OpenidRelyingParty/home.htm</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>authenticationFilter</filter-name>
        <url-pattern>*.nc</url-pattern>
    </filter-mapping>

    <!-- Authorization Filter -->
    <filter>
        <filter-name>authorizationFilter</filter-name>
        <filter-class>esg.datanode.security.app.AuthorizationFilter</filter-class>
        <init-param>
            <param-name>authorizationServiceClass</param-name>
            <param-value>esg.datanode.security.app.SAMLAuthorizationServiceFilterCollaborator</param-value>
        </init-param>
        <init-param>
            <param-name>authorizationServiceUrl</param-name>
            <param-value>https://esg.prototype.ucar.edu/saml/soap/secure/authorizationService.htm</param-value>
        </init-param>
        <init-param>
            <param-name>trustoreFile</param-name>
            <param-value>/usr/local/java/jre/lib/security/jssecacerts</param-value>
        </init-param>
        <init-param>
            <param-name>trustorePassword</param-name>
            <param-value>******</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>authorizationFilter</filter-name>
        <url-pattern>*.nc</url-pattern>
    </filter-mapping>

Example of logging configuration in log4j.xml:

  <logger name="esg" additivity="false">
    <level value="DEBUG"/>
    <appender-ref ref="threddsServlet"/>
  </logger>
Appendix: supporting legacy token-based authorization

A TDS installation can be configured to support both the newest openid/X509 ESG authorization mechanism, and the older token-based mechanism. This can be accomplished by chaining the authorization filters that intercept the data request, in the following order:

  • First the legacy eske.web.filters.security.AuthorizationTokenValidationFilter tries to detect the presence of an authorization token as an HTTP request parameter, and if found it validates with the Gateway and flags the request as "authorized"
  • If the request is not "authorized" already, the esg.datanode.security.app.AuthenticationFilter tries to detect the the authentication cookie in the request, and if not found it redirects the client to the ORP which proceeds with OpenID or X509 authentication.

To configure a TDS for chained authorization, the following additional steps must be taken:

  1. Install the following additional jars into <TDS INSTALL>/webapps/thredds/WEB-INF/lib:
    1. eske.jar
    2. hessian-3.0.20.jar
  2. Modify the file web.xml to include the additional eske.web.filters.security.AuthorizationTokenValidationFilter

Example configuration of web.xml to support additional legacy token-based authorization:

<!-- Filter definitions -->
<filter>
        <filter-name>AuthorizationTokenValidationFilter</filter-name>
        <filter-class>eske.web.filters.security.AuthorizationTokenValidationFilter</filter-class>
        <init-param>
                <param-name>ESG-NCAR</param-name>
                <param-value>https://esg.prototype.ucar.edu/remote/hessian/guest/secure/authorizationTokenService</param-value>
        </init-param>
        <init-param>
                <param-name>CADIS</param-name>
                <param-value>https://cadis.prototype.ucar.edu/remote/hessian/guest/secure/authorizationTokenService</param-value>
        </init-param>
</filter>
<!-- Authentication Filter -->
<!-- Authorization Filter -->

<!-- ...... -->

<!-- Filter mappings -->
<filter-mapping>
        <filter-name>AuthorizationTokenValidationFilter</filter-name>
        <url-pattern>/*</url-pattern>
</filter-mapping>
<!-- ...... -->

<!-- Restricted access servlet configuration  -->
<servlet>
    <servlet-name>RestrictedDataset</servlet-name>
    <servlet-class>thredds.servlet.restrict.RestrictedDatasetServlet</servlet-class>
    <init-param>
      <param-name>Authorizer</param-name>
      <param-value>eske.web.filters.security.AuthorizationTokenTDSAuthorizer</param-value>
      <!-- <param-value>esg.datanode.security.app.tds.TDSAuthorizer</param-value> -->
    </init-param>
    <init-param>
      <param-name>AuthorizerAllow</param-name>
      <param-value>127.0.0.1,128.117.12.2</param-value>
    </init-param>
 <load-on-startup>2</load-on-startup>
</servlet>

<!-- ...... -->

<!-- Restricted access servlet mapping -->
<servlet-mapping>
    <servlet-name>RestrictedDataset</servlet-name>
    <url-pattern>/restrictedAccess/*</url-pattern>
</servlet-mapping>

References

[1] http://www.unidata.ucar.edu/projects/THREDDS/

  • No labels