Expand my Community achievements bar.

Radically easy to access on brand approved content for distribution and omnichannel performant delivery. AEM Assets Content Hub and Dynamic Media with OpenAPI capabilities is now GA.
SOLVED

Page not redirecting on form submit

Avatar

Level 2

Hi,

So have a core form and a custom action which calls a servlet when the user submits the form. I modified the action attribute in container.html on the core form container component to call on my servlet.

 

Here is a code snippet of my container.html

<form data-sly-use.container="com.el.core.models.impl.v1.form.FormContainerImpl"
data-sly-use.grid="com.day.cq.wcm.foundation.model.responsivegrid.ResponsiveGrid"
method="POST" action="${container.action @selectors='formsubmission'}" id="${container.id}" name="${container.name}"

Then my servlet looks like this. 

// package here

import lombok.extern.slf4j.Slf4j;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;

@Slf4j
@Component(service = Servlet.class, property = {
Constants.SERVICE_DESCRIPTION + "=Servlet for Form Submission",
"sling.servlet.methods=" + HttpConstants.METHOD_POST,
"sling.servlet.resourceTypes=" + FormSubmissionServlet.SERVLET_RESOURCE_TYPE,
"sling.servlet.selectors=" + "formsubmission",
"sling.servlet.extensions=" + "html"
})
public class FormSubmissionServlet extends SlingAllMethodsServlet {

static final String SERVLET_RESOURCE_TYPE = "sling/servlet/default";

private static final String REDIRECT_URL = ":redirect";

@Override
protected void doPost(final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws ServletException, IOException {

String redirectUrl = request.getParameter(REDIRECT_URL);
// backend logic here

response.sendRedirect(redirectUrl);
}
}

 On the networks tab I can see that servlet is called but my thank you page is not loaded.

edeluyas_1-1669337967374.png

I can see also on the access.log the request. 

edeluyas_2-1669338040538.png

 

Any idea why it's not redirecting to the thank you page that i have set? 

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

@edeluyas 

Your POST request is being filtered and restricted by the “Apache Sling Referrer Filter” and “Adobe Granite CSRF Filter”. By default, the Apache Sling Referrer Filter blocks any incoming POST requests, and the Adobe Granite CSRF Filter blocks any incoming POST requests without the CSRF-Token token in the header.

You can solve this by following below steps

  • Allow incoming POST request in the Apache Sling Referrer Filter OSGI configurations, and
  • Remove the requirement of the CSRF-Token in the Adobe Granite CSRF Filter OSGI configurations.

Steps:

Configure Apache Sling Referrer Filter:

  1. Enable allow empty
  2. Remove the POST method from filters

In OSGI configurations (http://localhost:4502/system/console/configMgr), locate “Apache Sling Referrer Filter”. Enable the allow empty property, and remove the post method from filters property.
apache-sling-referrer-filter-after-1024x801.png
Configure Adobe Granite CSRF Filter

  1. Remove the POST method from filters

In OSGI configurations (http://localhost:4502/system/console/configMgr), locate “Adobe Granite CSRF Filter”. Remove the post method from filters property.

adobe-granite-csrf-filter-after-1024x844.png

Note: After making configurations to the two OSGI configurations, you should be able to make a POST request from your HTTP REST Client to your AEM instance.

For production, set Apache Sling Referrer Filter and Adobe Granite CSRF Filter settings back to default. Unless if you are giving access to other servers to make POST requests to your AEM application.

Reference: https://sourcedcode.com/blog/video-tutorial/how-to-make-simple-http-post-methods-in-aem-with-a-http-... 

View solution in original post

11 Replies

Avatar

Community Advisor

Hi @edeluyas,

Can you let us know,

  • How/What did you set redirectUrl parameter in form?
  • What is the value in "redirectUrl"?

I can able to redirect it.

package com.mysite.core.servlets;

import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.HttpConstants;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;

import javax.servlet.Servlet;
import java.io.IOException;
import java.rmi.ServerException;

@Component(service = Servlet.class, property = {Constants.SERVICE_DESCRIPTION + "=Simple Demo Redirect Servlet",
"sling.servlet.methods=" + HttpConstants.METHOD_POST, "sling.servlet.paths=" + "/bin/test/redirect"})

public class SimpleRedirectServlet extends SlingSafeMethodsServlet {

private static final long serialVersionUID = 2598426539166789516L;

@Override
protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp)
throws ServerException, IOException {
try {
resp.sendRedirect("/content/mysite/us/en.html");
} catch (Exception e) {
e.printStackTrace();
}
}
}

Screen Shot 2022-11-24 at 9.27.29 PM.png

Note: here I'm using GET (doGet) method instead doPost.

Hope that helps!

Regards,

Santosh

Avatar

Community Advisor

@edeluyas I can see in payload ":redirectis the actual page url which supposed to be passed in your code

 Can you try printing the variable redirectUrl

String redirectUrl = request.getParameter(REDIRECT_URL);

 and see what is the value you are getting.

Avatar

Level 2

@SantoshSai, I don't know why but on the page itself when I'm submitting, I can't see my logs on the access.logs or error.logs but on postman I can see it. So what I have tried is to hard-code the redirect for now and it is still the same it does not redirect to the page that I have configured. This is the value of the redirect but hard-coded for now.

response.sendRedirect("/content/el/au/en_au/ax-ootb-components/forms/thank-you.html");

Avatar

Community Advisor

@edeluyas - Try with doGet() instead doPost() 
The doPost() method in servlets is used to process the HTTP POST requests. It is used to submit the data from the browser to the server for processing. The data submitted with POST method type is sent in the message body so it is secure and cannot be seen in the URL.

Avatar

Level 2

@SantoshSai, I changed it to doGet() and it is redirecting now. My follow up question is why does redirect not work on post because one of the requirement is for me to set the method type to Post? Before I used servlet I used jsp to call my service and I used doPost on that but the redirect is working fine. What's the difference with servlet and service? 

Avatar

Correct answer by
Community Advisor

@edeluyas 

Your POST request is being filtered and restricted by the “Apache Sling Referrer Filter” and “Adobe Granite CSRF Filter”. By default, the Apache Sling Referrer Filter blocks any incoming POST requests, and the Adobe Granite CSRF Filter blocks any incoming POST requests without the CSRF-Token token in the header.

You can solve this by following below steps

  • Allow incoming POST request in the Apache Sling Referrer Filter OSGI configurations, and
  • Remove the requirement of the CSRF-Token in the Adobe Granite CSRF Filter OSGI configurations.

Steps:

Configure Apache Sling Referrer Filter:

  1. Enable allow empty
  2. Remove the POST method from filters

In OSGI configurations (http://localhost:4502/system/console/configMgr), locate “Apache Sling Referrer Filter”. Enable the allow empty property, and remove the post method from filters property.
apache-sling-referrer-filter-after-1024x801.png
Configure Adobe Granite CSRF Filter

  1. Remove the POST method from filters

In OSGI configurations (http://localhost:4502/system/console/configMgr), locate “Adobe Granite CSRF Filter”. Remove the post method from filters property.

adobe-granite-csrf-filter-after-1024x844.png

Note: After making configurations to the two OSGI configurations, you should be able to make a POST request from your HTTP REST Client to your AEM instance.

For production, set Apache Sling Referrer Filter and Adobe Granite CSRF Filter settings back to default. Unless if you are giving access to other servers to make POST requests to your AEM application.

Reference: https://sourcedcode.com/blog/video-tutorial/how-to-make-simple-http-post-methods-in-aem-with-a-http-... 

Avatar

Level 2

Hi @SantoshSai, sorry to get back to you this late. Just got busy with some other stuff. I've tried this already but still the issue persists. Anyways, I'll be using the get method for now and try to solve later how I can make post work on core forms. Thank you for your help! Greatly appreciated! 

Avatar

Community Advisor

Hi @edeluyas With the above code snippet, I can't see that you have defined any page URL in the variable REDIRECT_URL.

 

Redirect URL set using the core forms container component will get saved as redirect property on form container node. You would have to get that the redirect url. Here is the code snippet that you can use in your servlet to get the value.

 

Resource formContainerResource = request.getResource();
ValueMap valueMap = formContainerResource.adaptTo(ValueMap.class);
String redirect = valueMap.get("redirect", String.class);
response.sendRedirect(redirect);

 

Hope this helps.

Avatar

Level 2

I'm already getting the redirect. On the core container there's actually a hidden property there on the ootb for redirect url. I'm getting it via request parameters. Here is the more detailed image of my request. You can see the form data including the redirect. 

edeluyas_1-1669344032099.png

 

Avatar

Community Advisor

@edeluyas As @SantoshSai has suggested try printing the value of redirectUrl or debug this value. :redirect value is showing in the form data but it's value is not present on the request and that's the reason it would appear empty when you want to retrieve it's value from request parameter.

 

String redirectUrl = request.getParameter(REDIRECT_URL);