Christopher -

     Thanks for your reply. I am just going to respond to your first
question here, because it may be that I need to rethink the whole thing.

     /webapp_two is Geoserver, a complex web app that receives requests
for geolocated content and returns it in a number of different formats.
One of the way to distinguish content in Geoserver is to create and add
content to different 'workspaces', each with it's own name. When you
request content from Geoserver, the workspace name appears in the query
string.

     Geoserver only has basic authentication on an object by object
level. We are deploying it in a unversity that has a Centralized
Authentication Server, or CAS. CAS has a implementation that can be used
in tomcat, and that is realized as a set of filters.

     The first problem is that filters have the severe limitation of
only allowing one asterisk, making it impossible (as far as I can see)
to distinguish URLs on the basis of recognizing a pattern in the query
string. So this seems to necessitate recognizing the pattern in code,
modifying the URI in some recognizable way (or setting an attribute on
the request) and redirecting so that it gets intercepted by the CAS
filter(s).

     This makes it very difficult to work with Geoserver directly. While
the code is available, this is a massive project.

     On the other hand, I got my scheme to work more or less, but there
are problems. I got it to work by instantiating a RequestDispatcher by
getNamedDispatcher and finding the servlet name ("dispatcher") in
Geoserver's web.xml. However, I find that the content that Geoserver
returns embeds a number of URLs that point back to itself. I would have
to somehow intercept Geoserver's return in my fronting webapp and
rewrite those URLs.

      If I bite the bullet and attempt to change Geoserver, there is
another difficulty. I am attaching Geoserver's web.xml. Here also are
the CAS filters from my fronting webapp:

<filter>
<filter-name>CAS Single Sign Out Filter</filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
</filter>

<filter>
<filter-name>CAS Authentication Filter</filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
<init-param>
<param-name>casServerLoginUrl</param-name>
<param-value>https://auth.berkeley.edu/cas/login</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://linuxdev.lib.berkeley.edu:8443</param-value>
</init-param>
</filter>

<filter>
<filter-name>Ticket Validation Filter</filter-name>
<filter-class>org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter</filter-class>
<init-param>
<param-name>casServerUrlPrefix</param-name>
<param-value>https://auth.berkeley.edu/cas</param-value>
</init-param>
<init-param>
<param-name>serverName</param-name>
<param-value>https://linuxdev.lib.berkeley.edu:8443</param-value>
</init-param>
</filter>

<filter>
<filter-name>Http Servlet Request Wrapper Filter</filter-name>
<filter-class>org.jasig.cas.client.util.HttpServletRequestWrapperFilter</filter-class>
</filter>

<filter>
<filter-name>Assertion Thread Local Filter</filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>CAS Authentication Filter</filter-name>
<url-pattern>/PROTECTED/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>Ticket Validation Filter</filter-name>
<url-pattern>/PROTECTED/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>Http Servlet Request Wrapper Filter</filter-name>
<url-pattern>/PROTECTED/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>Assertion Thread Local Filter</filter-name>
<url-pattern>/PROTECTED/*</url-pattern>
</filter-mapping>

<filter-mapping>
<filter-name>CAS Single Sign Out Filter</filter-name>
<url-pattern>/PROTECTED/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
</listener>


     A major problem is how to integrate these two. If you can tell me,
maybe I can attempt to introduce the necessary changes to the Geoserver
servlet.

Garey Mills

On 10/19/2011 12:33 PM, Christopher Schultz wrote:
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1

 Garey,

 On 10/19/2011 1:56 PM, Garey Mills wrote:
 I want to use /webapp_one as an authentication front end for
 /webapp_two, since /webapp_two is a large, complex web app and I
 want to do authentication filtering on patterns in the query
 string. My scheme is to analyze the request URL in the body of
 /webapp_one. If it should be protected, rewrite it by adding a flag
 into the URI, so that it can be caught by my authentication filter
 in the web.xml, and redirect it back to /webapp_one. If it does not
 have to be protected, or if it has been protected by my filter,
 wrap the request so that it looks like a request to /webapp_two,
 get a   RequestDispatcher from /webapp_two's context, and 'include'
 the output from /webapp_two in the response from /webapp_one.
 That sounds absolutely insane. Can you explain why all this is necessary?

 The problem is that this is not working, and I believe that the
 problem is in how I am getting /webapp_two's ServletContext, or in
 how I am referring to the servlet in /webapp_two's context, since I
 am not seeing any activity from /webapp_two in the logs.

 Here are the particulars:

 * I have 'crossContext=true' set in /webapp_one's context * Here is
 my request wrapper

 public class MyRequestWrapper extends HttpServletRequestWrapper {
 String queryString = null; String uri = null; String contextPath =
 null; String pathTranslated = null;

 public GSRequestWrapper(HttpServletRequest req) { super(req); }

 public void setRequestURI(String newUri) { uri = newUri; } public
 String getRequestURI() { return uri; }
 Since this is a specialized filter, maybe this isn't a big deal, but
 you probably want to call super.getRequestURI() when none has been
 set. Similarly with the other methods.

 public StringBuffer getRequestURL() {

 StringBuffer sb = new StringBuffer(); sb.append(uri + "?" +
 queryString);
 Really?

 * Here is the code I use to create the wrapper

 MyRequestWrapper myReq = new MyRequestWrapper(req);

 myReq.setRequestURI(req.getRequestURI().replaceFirst("webapp_one",
 "webapp_two"));

 myReq.setContextPath(req.getContextPath().replaceFirst("webapp_one",


 "webapp_two"));
 myReq.setPathTranslated(req.getPathTranslated().replaceFirst("webapp_one",


 "webapp_two"));
 ServletContext twoContext = sc.getContext("/webapp_two");
 What do you do with twoContext after this point?

 * In /webapp_two, the url-pattern intercepted is '/*', so this is
 how I am trying to create the RequestDispatcher

 RequestDispatcher rd = twoContext.getRequestDispatcher("/");
 You want to use getRequestDispatcher() with a real path: I would
 recommend using the path that you are really trying to reach -- either
 the modified one (except that you don't want to have the context-path
 in the path because the RequestDispatcher will already know it's bound
 to a certain ServletContext) instead of just asking for "/".

 Also, I'm not entirely sure what happens to the HttpServletRequest
 when you get a request dispatcher using a path and then forward an
 existing request. I suspect that the filters and servlets on the other
 end see the path you used to fetch the dispatcher, otherwise you could
 never forward or include content that didn't match the original URI.

 Trying all this out, I see that the RequestDispatcher I am
 creating is not null, but I am not seeing any activity in
 /webapp_two, and the page returned is blank.
 Any error messages in the logs?

 Am I making a mistake in referring to the context of /webapp_two,
 or in how I am creating my request wrapper, or in how I am
 referring to the servlet in /webapp_two?
 I think things in general are okay (notwithstanding the very strange
 requirements, here) -- there must be some small detail that is
 out-of-place.

 I would try using the desired path when you fetch a RequestDispatcher
 instead of just using "/".

 - -chris
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.10 (MingW32)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

 iEYEARECAAYFAk6fJiAACgkQ9CaO5/Lv0PCEAgCeL+7kPrxL4CPS97kR5+04V+g8
 6JMAoLXHVsLq2MceN0cEt6U6sfcrU6d2
 =3WPe
 -----END PGP SIGNATURE-----

 ---------------------------------------------------------------------
 To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
 For additional commands, e-mail: users-h...@tomcat.apache.org



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd";>
<web-app>
    <display-name>GeoServer</display-name>
  
      <context-param>
    <param-name>serviceStrategy</param-name>
    <!-- Meaning of the different values :
         
         PARTIAL-BUFFER2
         - Partially buffers the first xKb to disk. Once that has buffered, the the 
           result is streamed to the user. This will allow for most errors to be caught
           early. 
           
         BUFFER
         - stores the entire response in memory first, before sending it off to
           the user (may run out of memory)

         SPEED
         - outputs directly to the response (and cannot recover in the case of an
           error)

         FILE
         - outputs to the local filesystem first, before sending it off to the user
      -->
    <param-value>PARTIAL-BUFFER2</param-value>
  </context-param>
  
  <!-- If true, enable versioning datastore as well -->
  <context-param>
    <param-name>enableVersioning</param-name>
    <param-value>true</param-value>
  </context-param>
  
  <context-param>
    <!-- see comments on the PARTIAL-BUFFER strategy -->
    <!-- this sets the size of the buffer.  default is "50" = 50kb -->

    <param-name>PARTIAL_BUFFER_STRATEGY_SIZE</param-name>
    <param-value>50</param-value>
  </context-param>
  
    <!-- 
    <context-param>
      <param-name>PROXY_BASE_URL</param-name>
      <param-value>http://82.58.146.45/geoserver</param-value>
    </context-param>
     -->
   
    <context-param>
       <param-name>GEOSERVER_DATA_DIR</param-name>
        <param-value>/opt/geoserver-data</param-value>
    </context-param> 
    
    <!-- pick up all spring application contexts -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/applicationContext.xml classpath*:/applicationSecurityContext.xml</param-value>
    </context-param>
    
    <filter>
     <filter-name>SessionDebugger</filter-name>
     <filter-class>org.geoserver.filters.SessionDebugFilter</filter-class>
    </filter>

    <filter>
     <filter-name>Spring Security Filter Chain Proxy</filter-name>
     <filter-class>org.springframework.security.util.FilterToBeanProxy</filter-class>
     <init-param>
       <param-name>targetClass</param-name>
       <param-value>org.springframework.security.util.FilterChainProxy</param-value>
     </init-param>
    </filter>
    
   <filter>
    <filter-name>Set Character Encoding</filter-name>
    <filter-class>org.vfny.geoserver.filters.SetCharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>

   <filter>
    <filter-name>Reverse Proxy Filter</filter-name>
    <filter-class>org.geoserver.filters.ReverseProxyFilter</filter-class>
    <init-param>
      <param-name>enabled</param-name>
      <param-value>false</param-value>
      <description>
        Whether to enable the reverse proxy filter or not. Defaults to false. Set to true
        in order for GeoServer to perform URL translation for the proxyfied base URL on
        textual content whose MIME type matches one of the regular expressions set through
        the mime-types init parameter.
      </description>
    </init-param>
    <init-param>
      <param-name>mime-types</param-name>
      <param-value>text/html.*,text/css.*,text/javascript.*,application/x-javascript.*</param-value>
      <description>
        Comma separated list of response MIME types the filter shall process in order to translate
        absolute urls using the configured proxyBaseUrl. Each token in the comma separated list
        is interpreted as a java regular expression.
      </description>
    </init-param>
   </filter>
   
   <filter>
     <filter-name>GZIP Compression Filter</filter-name>
     <filter-class>org.geoserver.filters.GZIPFilter</filter-class>
     <init-param>
         <!-- The compressed-types parameter is a comma-separated list of regular expressions.
              If a mime type matches any of the regular expressions then it will be compressed.
              -->
         <param-name>compressed-types</param-name>
         <param-value>text/.*,.*xml.*,application/json,application/x-javascript</param-value>
     </init-param>
   </filter>

   <filter>
     <filter-name>Request Logging Filter</filter-name>
     <filter-class>org.geoserver.filters.LoggingFilter</filter-class>
     <init-param>
         <!-- The 'enabled' parameter is a boolean value, "true" (case-insensitive) for true or
              any other value for false.  If enabled, then the logging will be performed;
              otherwise the logging filter will have no effect.  If not specified, this 
              parameter defaults to false.
              -->
         <param-name>enabled</param-name>
         <param-value>false</param-value>
     </init-param>
     <init-param>
     <!-- The 'log-request-bodies' parameter is a boolean value, "true" (case-insensitive) for
          true or any other value for false.  If enabled, then the logging will include the body
          of POST and PUT requests.  If not specified, this parameter defaults to false.
          Note that this may noticeably degrade responsiveness of your geoserver since it will
          not begin to process requests until the entire request body has been received by the 
          server.
          -->
     <param-name>log-request-bodies</param-name>
     <param-value>false</param-value>
     </init-param>
   </filter>
   
   <filter>
     <filter-name>Advanced Dispatch Filter</filter-name>
     <filter-class>org.geoserver.platform.AdvancedDispatchFilter</filter-class>
     <!-- 
     This filter allows for a single mapping to the spring dispatcher. However using /* as a mapping
     in a servlet mapping causes the servlet path to be "/" of the request. This causes problems with
     library like wicket and restlet. So this filter fakes the servlet path by assuming the first 
     component of the path is the mapped path. 
     -->
   </filter>
   
   <filter>
    <filter-name>Spring Delegating Filter</filter-name>
    <filter-class>org.geoserver.filters.SpringDelegatingFilter</filter-class>
    <!--
    This filter allows for filters to be loaded via spring rather than 
    registered here in web.xml.  One thing to note is that for such filters 
    init() is not called. INstead any initialization is performed via spring 
    ioc.
    -->
   </filter>
   
   <filter>
     <filter-name>Thread locals cleanup filter</filter-name>
     <filter-class>org.geoserver.filters.ThreadLocalsCleanupFilter</filter-class>
     <!-- 
     This filter cleans up thread locals Geotools is setting up for concurrency and performance
     reasons 
     -->
   </filter>

    <filter-mapping>
      <filter-name>SessionDebugger</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
      <filter-name>GZIP Compression Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
      <filter-name>Reverse Proxy Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
  
    <filter-mapping>
      <filter-name>Request Logging Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
   
    <!-- 
      If you want to use your security system comment out this one too
    -->
    <filter-mapping>
      <filter-name>Spring Security Filter Chain Proxy</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    
      <filter-mapping>
      <filter-name>Set Character Encoding</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
      <filter-name>Advanced Dispatch Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
      <filter-name>Spring Delegating Filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <filter-mapping>
      <filter-name>Thread locals cleanup filter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <!-- general initializer, should be first thing to execute -->
    <listener>
      <listener-class>org.geoserver.GeoserverInitStartupListener</listener-class>
    </listener>
    
    <!-- logging initializer, should execute before spring context startup -->
    <listener>
      <listener-class>org.geoserver.logging.LoggingStartupContextListener</listener-class>
    </listener>
  
    <!--  spring context loader -->
    <listener>
      <listener-class>org.geoserver.platform.GeoServerContextLoaderListener</listener-class>
    </listener>
    
    
    <!-- spring dispatcher servlet, dispatches all incoming requests -->
    <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    </servlet>
    
    <!-- single mapping to spring, this only works properly if the advanced dispatch filter is 
         active -->
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    
    <mime-mapping>
      <extension>xsl</extension>
      <mime-type>text/xml</mime-type>
    </mime-mapping>
    <mime-mapping>
      <extension>sld</extension>
      <mime-type>text/xml</mime-type>
    </mime-mapping>
  
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    
</web-app>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to