HTTPS not working with InjectPage or Class

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

HTTPS not working with InjectPage or Class

JumpStart
Hi,

I’ve found 2 situations where an HTTP URL is returned despite having set the whole application to “secure”.

* The 2 event handlers below are not correct - they return HTTP URLs (in, of course, a 302 redirect), not HTTPS URLs.

public class Page1 {

        @InjectPage
        private Page2 page2;

        Object onToPage2InjectPage() {
                return page2;
        }

        Object onToPage2Class() {
                return Page2.class;
        }

}

* Whereas PageLink and EventLink are correct - in Page1 they generated HTTPS URLs.

<body>
        <h1>Page 1</h1>
       
        <t:pagelink page="page2">To Page 2 (PageLink)</t:pagelink>
        <p/>
        <t:eventlink event="toPage2InjectPage">To Page 2 (InjectPage)</t:eventlink>
        <p/>
        <t:eventlink event="toPage2Class">To Page 2 (Class)</t:eventlink>
</body>

This DID work in my previous setup, which was Apache virtual host on port 443, handling the SSL, and proxying via AJP to Tapestry in Wildfly on port 8009.

What’s changed is that I’ve put an AWS ALB (Application Load Balancer) in front of Apache. ALB handles the SSL, forwards to Apache on port 80, which proxies via AJP to Tapestry in Wildfly on port 8009.

I think the HTTP headers on the requests are all intact. But even if they aren’t, shouldn’t the following configuration guarantee that the event handlers shown above return HTTPS URLs?

        public void contributeMetaDataLocator(MappedConfiguration<String, String> configuration) {
                configuration.add(MetaDataConstants.SECURE_PAGE, "true");
        }

I saw an earlier post that suggested doing the following, but it had the same result:

        public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration) {
                configuration.add(MetaDataConstants.SECURE_PAGE, "true");
        }

Regards,

Geoff

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: HTTPS not working with InjectPage or Class

JumpStart
This is getting urgent! Can someone tell me what handles the return types from an event handler? I urgently have to fix it to ensure it returns HTTPS.

BTW, I have a custom BaseURLSource in AppModule:

         public static void contributeServiceOverride(@SuppressWarnings("rawtypes") MappedConfiguration<Class, Object> configuration) {
                 configuration.add(BaseURLSource.class, new ConfiguredBaseURLSource());
         }

and I’ve determined that every time it is called it returns an https URL. It is NOT called when the 2 event handlers of my example are involved, which seems a bit odd.

Geoff

> On 14 Apr 2017, at 11:17 AM, JumpStart <[hidden email]> wrote:
>
> Hi,
>
> I’ve found 2 situations where an HTTP URL is returned despite having set the whole application to “secure”.
>
> * The 2 event handlers below are not correct - they return HTTP URLs (in, of course, a 302 redirect), not HTTPS URLs.
>
> public class Page1 {
>
> @InjectPage
> private Page2 page2;
>
> Object onToPage2InjectPage() {
> return page2;
> }
>
> Object onToPage2Class() {
> return Page2.class;
> }
>
> }
>
> * Whereas PageLink and EventLink are correct - in Page1 they generated HTTPS URLs.
>
> <body>
> <h1>Page 1</h1>
>
> <t:pagelink page="page2">To Page 2 (PageLink)</t:pagelink>
> <p/>
> <t:eventlink event="toPage2InjectPage">To Page 2 (InjectPage)</t:eventlink>
> <p/>
> <t:eventlink event="toPage2Class">To Page 2 (Class)</t:eventlink>
> </body>
>
> This DID work in my previous setup, which was Apache virtual host on port 443, handling the SSL, and proxying via AJP to Tapestry in Wildfly on port 8009.
>
> What’s changed is that I’ve put an AWS ALB (Application Load Balancer) in front of Apache. ALB handles the SSL, forwards to Apache on port 80, which proxies via AJP to Tapestry in Wildfly on port 8009.
>
> I think the HTTP headers on the requests are all intact. But even if they aren’t, shouldn’t the following configuration guarantee that the event handlers shown above return HTTPS URLs?
>
> public void contributeMetaDataLocator(MappedConfiguration<String, String> configuration) {
> configuration.add(MetaDataConstants.SECURE_PAGE, "true");
> }
>
> I saw an earlier post that suggested doing the following, but it had the same result:
>
> public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration) {
> configuration.add(MetaDataConstants.SECURE_PAGE, "true");
> }
>
> Regards,
>
> Geoff
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: HTTPS not working with InjectPage or Class

JumpStart
I think I’ve found the cause. It would be great if someone could confirm my logic.

The problem seems to be that the ALB is passing through a secure request with “http” scheme. Tapestry sees that it’s a secure request and assumes the scheme must be “https” so it returns a relative URL (because it returns LinkSecurity.SECURE), instead of generating an absolute URL with “https” scheme (achieved by returning LinkSecurity.FORCE_SECURE).

The place this happens is RequestSecurityManagerImpl’s method checkPageSecurity(String pageName), shown below, from T5.4.1:

    public LinkSecurity checkPageSecurity(String pageName)
    {
        if (!securityEnabled)
        {
            return request.isSecure() ? LinkSecurity.SECURE : LinkSecurity.INSECURE;
        }

        boolean securePage = isSecure(pageName);

        if (request.isSecure() == securePage)
        {
            return securePage ? LinkSecurity.SECURE : LinkSecurity.INSECURE;
        }

        // Return a value that will, ultimately, force an absolute URL.

        return securePage ? LinkSecurity.FORCE_SECURE : LinkSecurity.FORCE_INSECURE;
    }

It could be changed to either:

(a) always cause an absolute URL (by returning only LinkSecurity.FORCE_SECURE or LinkSecurity.FORCE_INSECURE); or
(b) only return a relative URL (by returning LinkSecurity.SECURE or LinkSecurity.INSECURE) if request.isSecure() and the scheme agree, eg.

        if (request.isSecure() == securePage)
        {
            if (request.isSecure() && request.getAttribute("servletAPI.scheme").equals("https")
                || !request.isSecure() && request.getAttribute("servletAPI.scheme").equals("http"))
            {
                    return securePage ? LinkSecurity.SECURE : LinkSecurity.INSECURE;
            }
            else
            {
                return securePage ? LinkSecurity.FORCE_SECURE : LinkSecurity.FORCE_INSECURE;
            }
        }

Agreed?

Geoff

> On 15 Apr 2017, at 2:08 PM, JumpStart <[hidden email]> wrote:
>
> This is getting urgent! Can someone tell me what handles the return types from an event handler? I urgently have to fix it to ensure it returns HTTPS.
>
> BTW, I have a custom BaseURLSource in AppModule:
>
> public static void contributeServiceOverride(@SuppressWarnings("rawtypes") MappedConfiguration<Class, Object> configuration) {
> configuration.add(BaseURLSource.class, new ConfiguredBaseURLSource());
> }
>
> and I’ve determined that every time it is called it returns an https URL. It is NOT called when the 2 event handlers of my example are involved, which seems a bit odd.
>
> Geoff
>
>> On 14 Apr 2017, at 11:17 AM, JumpStart <[hidden email] <mailto:[hidden email]>> wrote:
>>
>> Hi,
>>
>> I’ve found 2 situations where an HTTP URL is returned despite having set the whole application to “secure”.
>>
>> * The 2 event handlers below are not correct - they return HTTP URLs (in, of course, a 302 redirect), not HTTPS URLs.
>>
>> public class Page1 {
>>
>> @InjectPage
>> private Page2 page2;
>>
>> Object onToPage2InjectPage() {
>> return page2;
>> }
>>
>> Object onToPage2Class() {
>> return Page2.class;
>> }
>>
>> }
>>
>> * Whereas PageLink and EventLink are correct - in Page1 they generated HTTPS URLs.
>>
>> <body>
>> <h1>Page 1</h1>
>>
>> <t:pagelink page="page2">To Page 2 (PageLink)</t:pagelink>
>> <p/>
>> <t:eventlink event="toPage2InjectPage">To Page 2 (InjectPage)</t:eventlink>
>> <p/>
>> <t:eventlink event="toPage2Class">To Page 2 (Class)</t:eventlink>
>> </body>
>>
>> This DID work in my previous setup, which was Apache virtual host on port 443, handling the SSL, and proxying via AJP to Tapestry in Wildfly on port 8009.
>>
>> What’s changed is that I’ve put an AWS ALB (Application Load Balancer) in front of Apache. ALB handles the SSL, forwards to Apache on port 80, which proxies via AJP to Tapestry in Wildfly on port 8009.
>>
>> I think the HTTP headers on the requests are all intact. But even if they aren’t, shouldn’t the following configuration guarantee that the event handlers shown above return HTTPS URLs?
>>
>> public void contributeMetaDataLocator(MappedConfiguration<String, String> configuration) {
>> configuration.add(MetaDataConstants.SECURE_PAGE, "true");
>> }
>>
>> I saw an earlier post that suggested doing the following, but it had the same result:
>>
>> public static void contributeApplicationDefaults(MappedConfiguration<String, String> configuration) {
>> configuration.add(MetaDataConstants.SECURE_PAGE, "true");
>> }
>>
>> Regards,
>>
>> Geoff
>>
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: HTTPS not working with InjectPage or Class

JumpStart
I’ve created https://issues.apache.org/jira/browse/TAP5-2577 .
 

> On 15 Apr 2017, at 6:36 PM, JumpStart <[hidden email]> wrote:
>
>
>         if (request.isSecure() == securePage)
>         {
>             if (request.isSecure() && request.getAttribute("servletAPI.scheme").equals("https")
>        || !request.isSecure() && request.getAttribute("servletAPI.scheme").equals("http"))
>             {
>                     return securePage ? LinkSecurity.SECURE : LinkSecurity.INSECURE;
>             }
>             else
>             {
>                 return securePage ? LinkSecurity.FORCE_SECURE : LinkSecurity.FORCE_INSECURE;
>             }
>         }
>
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: HTTPS not working with InjectPage or Class

Thiago H. de Paula Figueiredo
In reply to this post by JumpStart
Hello, Geoff!

Event handler method return values are processed
by ComponentEventResultProcessor instances.

By the way, considering you have a load balancer, the projects I work in my
day job have HTTPS handled in the load balancer (haproxy) and the Tapestry
webapp itself runs *without* HTTPS/security turned on.

While your suggestion (thank you very much for it and the ticket, by the
way!) isn't worked on Tapestry itself, you can always override, decorate or
advise the RequestSecurityManager service.


On Sat, Apr 15, 2017 at 3:08 AM, JumpStart <
[hidden email]> wrote:

> This is getting urgent! Can someone tell me what handles the return types
> from an event handler? I urgently have to fix it to ensure it returns HTTPS.
>
> BTW, I have a custom BaseURLSource in AppModule:
>
>          public static void contributeServiceOverride(@SuppressWarnings("rawtypes")
> MappedConfiguration<Class, Object> configuration) {
>                  configuration.add(BaseURLSource.class, new
> ConfiguredBaseURLSource());
>          }
>
> and I’ve determined that every time it is called it returns an https URL.
> It is NOT called when the 2 event handlers of my example are involved,
> which seems a bit odd.
>
> Geoff
>
> > On 14 Apr 2017, at 11:17 AM, JumpStart <geoff.callender.jumpstart@
> gmail.com> wrote:
> >
> > Hi,
> >
> > I’ve found 2 situations where an HTTP URL is returned despite having set
> the whole application to “secure”.
> >
> > * The 2 event handlers below are not correct - they return HTTP URLs
> (in, of course, a 302 redirect), not HTTPS URLs.
> >
> > public class Page1 {
> >
> >       @InjectPage
> >       private Page2 page2;
> >
> >       Object onToPage2InjectPage() {
> >               return page2;
> >       }
> >
> >       Object onToPage2Class() {
> >               return Page2.class;
> >       }
> >
> > }
> >
> > * Whereas PageLink and EventLink are correct - in Page1 they generated
> HTTPS URLs.
> >
> > <body>
> >       <h1>Page 1</h1>
> >
> >       <t:pagelink page="page2">To Page 2 (PageLink)</t:pagelink>
> >       <p/>
> >       <t:eventlink event="toPage2InjectPage">To Page 2
> (InjectPage)</t:eventlink>
> >       <p/>
> >       <t:eventlink event="toPage2Class">To Page 2 (Class)</t:eventlink>
> > </body>
> >
> > This DID work in my previous setup, which was Apache virtual host on
> port 443, handling the SSL, and proxying via AJP to Tapestry in Wildfly on
> port 8009.
> >
> > What’s changed is that I’ve put an AWS ALB (Application Load Balancer)
> in front of Apache. ALB handles the SSL, forwards to Apache on port 80,
> which proxies via AJP to Tapestry in Wildfly on port 8009.
> >
> > I think the HTTP headers on the requests are all intact. But even if
> they aren’t, shouldn’t the following configuration guarantee that the event
> handlers shown above return HTTPS URLs?
> >
> >       public void contributeMetaDataLocator(MappedConfiguration<String,
> String> configuration) {
> >               configuration.add(MetaDataConstants.SECURE_PAGE, "true");
> >       }
> >
> > I saw an earlier post that suggested doing the following, but it had the
> same result:
> >
> >       public static void contributeApplicationDefaults(MappedConfiguration<String,
> String> configuration) {
> >               configuration.add(MetaDataConstants.SECURE_PAGE, "true");
> >       }
> >
> > Regards,
> >
> > Geoff
> >
>
>


--
Thiago
Loading...