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 <geoff.callender.jumpst...@gmail.com> 
> 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.jumpst...@gmail.com 
>> <mailto:geoff.callender.jumpst...@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
>> 
> 

Reply via email to