You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Jeremy <jk...@jkassis.com> on 2005/08/10 08:01:08 UTC

4.0: HTTP / HTTPS Protocol Switching

I'm submitting a patch to enable HTTP / HTTPS protocol switching that comes
on the heels of a couple of days of research. Hope you dig it! Here's the
background on why and what I did:

 

1.	First, I tried to get the container do it. Unfortunately, Tomcat is
good about getting you into HTTPS using a <security-constraint>, but not
out. There's no way to specify that a resource / page *must* be accessed
with HTTP.
2.	So, I setup redirects in Tapestry. I added a property to my BasePage
(BasePage.secure) that indicates whether or not the page should be accessed
with HTTPS. Then in the BasePage.pageValidate method, I throw a redirect to
switch the protocol from http > https OR https > http as necessary. This
works, but if a listener method in PAGE-A (set for http access) uses the
RequestCycle to activate PAGE-B (set for http access), then the pageValidate
method of PAGE-B throws a redirect to switch back to HTTP, the browser makes
a request for PAGE-A again using http, and the app's caught in an infinite
redirect loop. 
3.	So, I setup the BasePage.pageValidate to just allow access when
https is used. But now the app has the same problem it had when I had
redirects working in tomcat: it can't get back to http.
4.	So, I created a new ILinkRenderer that grabs the page name from its
underlying ILink, uses a PageSpecificationResolver to grab the page
specification, check for the declaration of BasePage.secure, and call
getAbsoluteUrl of the underlying ILink as necessary to output an HTTP or
HTTPS link. It works pretty well. But it doesn't work for Forms, only for
AbstractLinkComponent and its descendents. And it's hard to grab the page
name from the ILink at this point in rendering -  after the LinkFactoryImpl
applies ServiceEncoders that mess everything up.
5.	At this point I decided to stop hacking around the issue and patch
the source. I gave EngineServiceLink two new parameters: _scheme and _port.
When a client calls EngineServiceLink.getUrl(), EngineServiceLink checks its
_scheme and _port properties. If _scheme is not specified or the same as the
scheme used to make the current request, getUrl() does exactly what it did
before: it returns a relative url. If _scheme is specified and not equal to
the scheme used to make the current request, getUrl() returns an absolute
URL with the specified scheme and port through its getAbsoluteUrl method.
Then I set up my engine services to check for the BasePage.secure property
(what the custom ILinkRenderer did before) and override the default scheme
and port for the link.
6.	Of course, I updated all the references to
LinkFactoryImpl.constructUrl in the default engine services and tests.

 

Here's the patch:

 

 

 

 

 


RE: 4.0: HTTP / HTTPS Protocol Switching

Posted by Jeremy <jk...@jkassis.com>.
> wow.  I asked about this just a few days ago.  But I don't quite
> understand the last mile.  Once Tapestry is patched, what do I have to
> do in my webapp to turn this on for my credit card entry page..
 > We have to override all Engine Services?

Yes. First override all engine services in hivemind. Here's an example:

  	<contribution
configuration-id="tapestry.services.ApplicationServices">
       <service name="action" object="service:Action" />
       <service name="direct" object="service:Direct" />
       <service name="page" object="service:Page" />
    </contribution>
  	
  	<service-point id="SecurePageDetector"
interface="com.jkassis.percolate.tapestry.service.SecurePageDetector">
    	<invoke-factory >
      		<construct
class="com.jkassis.percolate.tapestry.service.SecurePageDetector">
        		<set-object property="pageSpecificationResolver"
value="service:tapestry.page.PageSpecificationResolver"/>
      		</construct>
    	</invoke-factory>
  	</service-point>
  
  
  	<service-point id="Direct"
interface="org.apache.tapestry.engine.IEngineService">
    	<invoke-factory>
      		<construct
class="com.jkassis.percolate.tapestry.service.DirectService">
        		<set-object property="responseRenderer"
value="infrastructure:responseRenderer"/>
        		<set-object property="request"
value="infrastructure:request"/>
        		<set-object property="linkFactory"
value="service:tapestry.url.LinkFactory"/>       
        		<set-object property="securePageDetector"
value="service:SecurePageDetector"/>
      		</construct>
    	</invoke-factory>
  	</service-point>


You will notice that I'm injecting my DirectService with a helper service,
the SecurePageDetector. That's what loads the page specification and looks
for the isSecure property.

Source for all this is attached.

 
> 
> ps - I am currently looking into using urlrewrite to do the http/https
> redirect management, but keeping the isSecure metadata tied with the
> page, and have the urls be correctly generated is a polished option.

Thanks. I agree. Lets hope the tapestry team agrees and integrates the
patch!



> 
> Jeremy wrote:
> > I'm submitting a patch to enable HTTP / HTTPS protocol switching that
> > comes on the heels of a couple of days of research. Hope you dig it!
> > Here's the background on why and what I did:
> >
> >
> >
> >    1. First, I tried to get the container do it. Unfortunately, Tomcat
> >       is good about getting you into HTTPS using a
> >       <security-constraint>, but not out. There's no way to specify that
> >       a resource / page **must** be accessed with HTTP.
> >    2. So, I setup redirects in Tapestry. I added a property to my
> >       BasePage (BasePage.secure) that indicates whether or not the page
> >       should be accessed with HTTPS. Then in the BasePage.pageValidate
> >       method, I throw a redirect to switch the protocol from http >
> >       https OR https > http as necessary. This works, but if a listener
> >       method in PAGE-A (set for http access) uses the RequestCycle to
> >       activate PAGE-B (set for http access), then the pageValidate
> >       method of PAGE-B throws a redirect to switch back to HTTP, the
> >       browser makes a request for PAGE-A again using http, and the app's
> >       caught in an infinite redirect loop.
> >    3. So, I setup the BasePage.pageValidate to just allow access when
> >       https is used. But now the app has the same problem it had when I
> >       had redirects working in tomcat: it can't get back to http.
> >    4. So, I created a new ILinkRenderer that grabs the page name from
> >       its underlying ILink, uses a PageSpecificationResolver to grab the
> >       page specification, check for the declaration of BasePage.secure,
> >       and call getAbsoluteUrl of the underlying ILink as necessary to
> >       output an HTTP or HTTPS link. It works pretty well. But it doesn't
> >       work for Forms, only for AbstractLinkComponent and its
> >       descendents. And it's hard to grab the page name from the ILink at
> >       this point in rendering -  after the LinkFactoryImpl applies
> >       ServiceEncoders that mess everything up.
> >    5. At this point I decided to stop hacking around the issue and patch
> >       the source. I gave EngineServiceLink two new parameters: _scheme
> >       and _port. When a client calls EngineServiceLink.getUrl(),
> >       EngineServiceLink checks its _scheme and _port properties. If
> >       _scheme is not specified or the same as the scheme used to make
> >       the current request, getUrl() does exactly what it did before: it
> >       returns a relative url. If _scheme is specified and not equal to
> >       the scheme used to make the current request, getUrl() returns an
> >       absolute URL with the specified scheme and port through its
> >       getAbsoluteUrl method. Then I set up my engine services to check
> >       for the BasePage.secure property (what the custom ILinkRenderer
> >       did before) and override the default scheme and port for the link.
> >    6. Of course, I updated all the references to
> >       LinkFactoryImpl.constructUrl in the default engine services and
> tests.
> >
> >
> >
> > Here's the patch:
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> 
> 



RE: 4.0: HTTP / HTTPS Protocol Switching

Posted by Jeremy <jk...@jkassis.com>.
Of course, you should also set

  <property name="secure" initial-value="ognl: true" />

On your credit card page.

> -----Original Message-----
> From: Fernando Padilla [mailto:fern@alum.mit.edu]
> Sent: Wednesday, August 10, 2005 8:01 AM
> To: Tapestry users
> Subject: Re: 4.0: HTTP / HTTPS Protocol Switching
> 
> wow.  I asked about this just a few days ago.  But I don't quite
> understand the last mile.  Once Tapestry is patched, what do I have to
> do in my webapp to turn this on for my credit card entry page..
> 
> We have to override all Engine Services?
> 
> 
> ps - I am currently looking into using urlrewrite to do the http/https
> redirect management, but keeping the isSecure metadata tied with the
> page, and have the urls be correctly generated is a polished option.
> https://urlrewrite.dev.java.net/
> 
> Jeremy wrote:
> > I'm submitting a patch to enable HTTP / HTTPS protocol switching that
> > comes on the heels of a couple of days of research. Hope you dig it!
> > Here's the background on why and what I did:
> >
> >
> >
> >    1. First, I tried to get the container do it. Unfortunately, Tomcat
> >       is good about getting you into HTTPS using a
> >       <security-constraint>, but not out. There's no way to specify that
> >       a resource / page **must** be accessed with HTTP.
> >    2. So, I setup redirects in Tapestry. I added a property to my
> >       BasePage (BasePage.secure) that indicates whether or not the page
> >       should be accessed with HTTPS. Then in the BasePage.pageValidate
> >       method, I throw a redirect to switch the protocol from http >
> >       https OR https > http as necessary. This works, but if a listener
> >       method in PAGE-A (set for http access) uses the RequestCycle to
> >       activate PAGE-B (set for http access), then the pageValidate
> >       method of PAGE-B throws a redirect to switch back to HTTP, the
> >       browser makes a request for PAGE-A again using http, and the app's
> >       caught in an infinite redirect loop.
> >    3. So, I setup the BasePage.pageValidate to just allow access when
> >       https is used. But now the app has the same problem it had when I
> >       had redirects working in tomcat: it can't get back to http.
> >    4. So, I created a new ILinkRenderer that grabs the page name from
> >       its underlying ILink, uses a PageSpecificationResolver to grab the
> >       page specification, check for the declaration of BasePage.secure,
> >       and call getAbsoluteUrl of the underlying ILink as necessary to
> >       output an HTTP or HTTPS link. It works pretty well. But it doesn't
> >       work for Forms, only for AbstractLinkComponent and its
> >       descendents. And it's hard to grab the page name from the ILink at
> >       this point in rendering -  after the LinkFactoryImpl applies
> >       ServiceEncoders that mess everything up.
> >    5. At this point I decided to stop hacking around the issue and patch
> >       the source. I gave EngineServiceLink two new parameters: _scheme
> >       and _port. When a client calls EngineServiceLink.getUrl(),
> >       EngineServiceLink checks its _scheme and _port properties. If
> >       _scheme is not specified or the same as the scheme used to make
> >       the current request, getUrl() does exactly what it did before: it
> >       returns a relative url. If _scheme is specified and not equal to
> >       the scheme used to make the current request, getUrl() returns an
> >       absolute URL with the specified scheme and port through its
> >       getAbsoluteUrl method. Then I set up my engine services to check
> >       for the BasePage.secure property (what the custom ILinkRenderer
> >       did before) and override the default scheme and port for the link.
> >    6. Of course, I updated all the references to
> >       LinkFactoryImpl.constructUrl in the default engine services and
> tests.
> >
> >
> >
> > Here's the patch:
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


RE: 4.0: HTTP / HTTPS Protocol Switching

Posted by Jeremy <jk...@jkassis.com>.
Also note that the patch applies to release-4-0-beta-3

> -----Original Message-----
> From: Fernando Padilla [mailto:fern@alum.mit.edu]
> Sent: Wednesday, August 10, 2005 8:01 AM
> To: Tapestry users
> Subject: Re: 4.0: HTTP / HTTPS Protocol Switching
> 
> wow.  I asked about this just a few days ago.  But I don't quite
> understand the last mile.  Once Tapestry is patched, what do I have to
> do in my webapp to turn this on for my credit card entry page..
> 
> We have to override all Engine Services?
> 
> 
> ps - I am currently looking into using urlrewrite to do the http/https
> redirect management, but keeping the isSecure metadata tied with the
> page, and have the urls be correctly generated is a polished option.
> https://urlrewrite.dev.java.net/
> 
> Jeremy wrote:
> > I'm submitting a patch to enable HTTP / HTTPS protocol switching that
> > comes on the heels of a couple of days of research. Hope you dig it!
> > Here's the background on why and what I did:
> >
> >
> >
> >    1. First, I tried to get the container do it. Unfortunately, Tomcat
> >       is good about getting you into HTTPS using a
> >       <security-constraint>, but not out. There's no way to specify that
> >       a resource / page **must** be accessed with HTTP.
> >    2. So, I setup redirects in Tapestry. I added a property to my
> >       BasePage (BasePage.secure) that indicates whether or not the page
> >       should be accessed with HTTPS. Then in the BasePage.pageValidate
> >       method, I throw a redirect to switch the protocol from http >
> >       https OR https > http as necessary. This works, but if a listener
> >       method in PAGE-A (set for http access) uses the RequestCycle to
> >       activate PAGE-B (set for http access), then the pageValidate
> >       method of PAGE-B throws a redirect to switch back to HTTP, the
> >       browser makes a request for PAGE-A again using http, and the app's
> >       caught in an infinite redirect loop.
> >    3. So, I setup the BasePage.pageValidate to just allow access when
> >       https is used. But now the app has the same problem it had when I
> >       had redirects working in tomcat: it can't get back to http.
> >    4. So, I created a new ILinkRenderer that grabs the page name from
> >       its underlying ILink, uses a PageSpecificationResolver to grab the
> >       page specification, check for the declaration of BasePage.secure,
> >       and call getAbsoluteUrl of the underlying ILink as necessary to
> >       output an HTTP or HTTPS link. It works pretty well. But it doesn't
> >       work for Forms, only for AbstractLinkComponent and its
> >       descendents. And it's hard to grab the page name from the ILink at
> >       this point in rendering -  after the LinkFactoryImpl applies
> >       ServiceEncoders that mess everything up.
> >    5. At this point I decided to stop hacking around the issue and patch
> >       the source. I gave EngineServiceLink two new parameters: _scheme
> >       and _port. When a client calls EngineServiceLink.getUrl(),
> >       EngineServiceLink checks its _scheme and _port properties. If
> >       _scheme is not specified or the same as the scheme used to make
> >       the current request, getUrl() does exactly what it did before: it
> >       returns a relative url. If _scheme is specified and not equal to
> >       the scheme used to make the current request, getUrl() returns an
> >       absolute URL with the specified scheme and port through its
> >       getAbsoluteUrl method. Then I set up my engine services to check
> >       for the BasePage.secure property (what the custom ILinkRenderer
> >       did before) and override the default scheme and port for the link.
> >    6. Of course, I updated all the references to
> >       LinkFactoryImpl.constructUrl in the default engine services and
> tests.
> >
> >
> >
> > Here's the patch:
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org


Re: 4.0: HTTP / HTTPS Protocol Switching

Posted by Fernando Padilla <fe...@alum.mit.edu>.
wow.  I asked about this just a few days ago.  But I don't quite
understand the last mile.  Once Tapestry is patched, what do I have to
do in my webapp to turn this on for my credit card entry page..

We have to override all Engine Services?


ps - I am currently looking into using urlrewrite to do the http/https
redirect management, but keeping the isSecure metadata tied with the
page, and have the urls be correctly generated is a polished option.
https://urlrewrite.dev.java.net/

Jeremy wrote:
> I’m submitting a patch to enable HTTP / HTTPS protocol switching that
> comes on the heels of a couple of days of research. Hope you dig it!
> Here’s the background on why and what I did:
> 
>  
> 
>    1. First, I tried to get the container do it. Unfortunately, Tomcat
>       is good about getting you into HTTPS using a
>       <security-constraint>, but not out. There’s no way to specify that
>       a resource / page **must** be accessed with HTTP.
>    2. So, I setup redirects in Tapestry. I added a property to my
>       BasePage (BasePage.secure) that indicates whether or not the page
>       should be accessed with HTTPS. Then in the BasePage.pageValidate
>       method, I throw a redirect to switch the protocol from http >
>       https OR https > http as necessary. This works, but if a listener
>       method in PAGE-A (set for http access) uses the RequestCycle to
>       activate PAGE-B (set for http access), then the pageValidate
>       method of PAGE-B throws a redirect to switch back to HTTP, the
>       browser makes a request for PAGE-A again using http, and the app’s
>       caught in an infinite redirect loop.
>    3. So, I setup the BasePage.pageValidate to just allow access when
>       https is used. But now the app has the same problem it had when I
>       had redirects working in tomcat: it can’t get back to http.
>    4. So, I created a new ILinkRenderer that grabs the page name from
>       its underlying ILink, uses a PageSpecificationResolver to grab the
>       page specification, check for the declaration of BasePage.secure,
>       and call getAbsoluteUrl of the underlying ILink as necessary to
>       output an HTTP or HTTPS link. It works pretty well. But it doesn’t
>       work for Forms, only for AbstractLinkComponent and its
>       descendents. And it’s hard to grab the page name from the ILink at
>       this point in rendering –  after the LinkFactoryImpl applies
>       ServiceEncoders that mess everything up.
>    5. At this point I decided to stop hacking around the issue and patch
>       the source. I gave EngineServiceLink two new parameters: _scheme
>       and _port. When a client calls EngineServiceLink.getUrl(),
>       EngineServiceLink checks its _scheme and _port properties. If
>       _scheme is not specified or the same as the scheme used to make
>       the current request, getUrl() does exactly what it did before: it
>       returns a relative url. If _scheme is specified and not equal to
>       the scheme used to make the current request, getUrl() returns an
>       absolute URL with the specified scheme and port through its
>       getAbsoluteUrl method. Then I set up my engine services to check
>       for the BasePage.secure property (what the custom ILinkRenderer
>       did before) and override the default scheme and port for the link.
>    6. Of course, I updated all the references to
>       LinkFactoryImpl.constructUrl in the default engine services and tests.
> 
>  
> 
> Here’s the patch:

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-user-help@jakarta.apache.org