Java CQ5:调用 Post servlet 时发生 403 Forbidden
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22799024/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
CQ5: 403 Forbidden occurs when call a Post servlet
提问by Tien Nguyen
Hi I'm using this code to create a Post method for my CQ5 example application.
嗨,我正在使用此代码为我的 CQ5 示例应用程序创建一个 Post 方法。
package com.adobe.cq.sling;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.rmi.ServerException;
import java.util.Dictionary;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.felix.scr.annotations.Reference;
import org.osgi.service.component.ComponentContext;
import javax.jcr.Session;
import javax.jcr.Node;
import org.json.simple.JSONObject;
import java.util.UUID;
@SlingServlet(paths="/bin/mySearchServlet", methods = "POST", metatype=true)
public class HandleClaim extends org.apache.sling.api.servlets.SlingAllMethodsServlet {
private static final long serialVersionUID = 2598426539166789515L;
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServerException, IOException {
try
{
//Get the submitted form data that is sent from the
//CQ web page
String id = UUID.randomUUID().toString();
String firstName = request.getParameter("firstName");
String lastName = request.getParameter("lastName");
String address = request.getParameter("address");
String cat = request.getParameter("cat");
String state = request.getParameter("state");
String details = request.getParameter("details");
String date = request.getParameter("date");
String city = request.getParameter("city");
//Encode the submitted form data to JSON
JSONObject obj=new JSONObject();
obj.put("id",id);
obj.put("firstname",firstName);
obj.put("lastname",lastName);
obj.put("address",address);
obj.put("cat",cat);
obj.put("state",state);
obj.put("details",details);
obj.put("date",date);
obj.put("city",city);
//Get the JSON formatted data
String jsonData = obj.toJSONString();
//Return the JSON formatted data
response.getWriter().write(jsonData);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
it work ok with a GET request. But for a POST(doPost) request i recevied a message: 403 Forbidden
. What i should do to resolve this issue ?
它可以与 GET 请求一起使用。但是对于 POST(doPost) 请求,我收到一条消息:403 Forbidden
。我应该怎么做才能解决这个问题?
采纳答案by Tien Nguyen
This issue will never happen If you call the method from internal client (for example: jsp file, ajax or Servlets that located in your application). However if you call it from external client (another website or REST client plugin...) CQ security filter will be triggered to prevent your action then return 403 error to remove this please follow these steps:
如果您从内部客户端(例如:位于您的应用程序中的 jsp 文件、ajax 或 Servlet)调用该方法,则永远不会发生此问题。但是,如果您从外部客户端(另一个网站或 REST 客户端插件...)调用它,将触发 CQ 安全过滤器以阻止您的操作,然后返回 403 错误以将其删除,请按照以下步骤操作:
1/ http://localhost:4502/system/console/configMgr
2/ Search for 'Apache Sling Referrer Filter'
3/ Remove POST method from the filter. Then you can call your POST method anywhere.
1/ http://localhost:4502/system/console/configMgr
2/ 搜索“Apache Sling Referrer Filter”
3/ 从过滤器中删除 POST 方法。然后你可以在任何地方调用你的 POST 方法。
回答by Bertrand Delacretaz
As mentioned at http://sling.apache.org/documentation/the-sling-engine/servlets.html, a servlet using the sling.servlet.paths
property might be ignored unless its path is included in the Execution Paths (servletresolver.paths
) configuration setting of the SlingServletResolver service. You should find that configuration at /system/console/configMgr/org.apache.sling.servlets.resolver.SlingServletResolver
.
如http://sling.apache.org/documentation/the-sling-engine/servlets.html 所述,使用该sling.servlet.paths
属性的 servlet可能会被忽略,除非其路径包含在servletresolver.paths
SlingServletResolver 服务的 Execution Paths ( ) 配置设置中. 您应该在 中找到该配置/system/console/configMgr/org.apache.sling.servlets.resolver.SlingServletResolver
。
In your case I suppose the /bin/mySearchServlet path is not included in that configuration parameter and causes CQ to return a 403 status. If that's right you can either add your path there (assuming you understand the security implications) or mount your servlets on one of the paths that's configured there.
在您的情况下,我认为 /bin/mySearchServlet 路径未包含在该配置参数中并导致 CQ 返回 403 状态。如果这是正确的,您可以在那里添加您的路径(假设您了解安全隐患)或将您的 servlet 安装在那里配置的路径之一上。
Note that it's best to avoid mounting servlet on paths if possible, creating a resource at the desired path is preferred as mentioned on that documentation page.
请注意,如果可能,最好避免在路径上安装 servlet,如该文档页面所述,首选在所需路径上创建资源。
回答by TechNiks
I am also using the same code for similar set of requirements and i was stuck on this error. I have solved it.
我也使用相同的代码来满足类似的需求,但我被这个错误困住了。我已经解决了。
PFB the steps. Either of them/All might work for you as well.
PFB 步骤。它们中的任何一个/全部也可能对您有用。
I have however used the annotations differently.
@Component( immediate = true, metatype = true, label = "Engage Now Form", description = "Engage Now Form") @Service @Properties({ @Property(name = "sling.servlet.paths", value = {"/bin/myServlet"}), @Property(name = "sling.servlet.methods", value = {"POST"}) })
I have given permission to my /bin/myServlet in the org.apache.sling.servlets.resolver.SlingServletResolver.
Used the poster plugin - set the referer in the header to some html existing in your site heirarchy other wise it will give 403 forbidden error. Also mention the parameters to send and go to content to send and say body from parameters. The below text box shall be populated. Now try posting the data.
For the CQ specific part :- i have implemented an AJAX based solution with forms where i send the POST call using AJAX on submit click. I also have a custom action in place with a forward.jsp containing the following code.
final ValueMap properties = ResourceUtil.getValueMap(resource); String path = properties.get("customRedirectPath", ""); //path = /bin/myServlet FormsHelper.setForwardPath(slingRequest, path); FormsHelper.setRedirectToReferrer(request, true);
然而,我以不同的方式使用了注释。
@Component(immediate = true, metatype = true, label = "Engage Now Form", description = "Engage Now Form") @Service @Properties({ @Property(name = "sling.servlet.paths", value = {" /bin/myServlet"}), @Property(name = "sling.servlet.methods", value = {"POST"}) })
我已在 org.apache.sling.servlets.resolver.SlingServletResolver 中授予我的 /bin/myServlet 权限。
使用了海报插件 - 将标头中的引用设置为站点层次结构中存在的一些 html,否则它会给出 403 禁止错误。还要提到要发送的参数并转到要发送的内容并从参数中说出正文。应填充以下文本框。现在尝试发布数据。
对于 CQ 特定部分:- 我已经实现了一个基于 AJAX 的解决方案,其中包含我在提交点击时使用 AJAX 发送 POST 调用的表单。我还有一个包含以下代码的 forward.jsp 的自定义操作。
最终 ValueMap 属性 = ResourceUtil.getValueMap(resource); String path = properties.get("customRedirectPath", ""); //path = /bin/myServlet FormsHelper.setForwardPath(slingRequest, path); FormsHelper.setRedirectToReferrer(request, true);
My AJAX call is :-
我的 AJAX 调用是:-
argsObject = {
oServiceUrl: "/bin/myServlet",
oAjaxFormat: "html",
oDataForAjax: $thisForm.serialize(),
oAjaxCommMethod: "POST",
oSuccessCallback: onSubmitSuccessCallback,
oErrorCallback: onSubmitErrorCallback
}
I am able to execute my servlet once this POST call is executed and i recieve a valid response as desired.
一旦执行此 POST 调用,我就可以执行我的 servlet,并且我收到了所需的有效响应。
Let me know if these steps help.
如果这些步骤有帮助,请告诉我。
回答by MRodriguez08
In addition to the other answers, If you are on AEM 6.1 this issue can also be caused by a CSRF Configuration as explained on this post.
除了其他的答案,如果你是AEM 6.1这个问题也可以通过CSRF配置上解释引起的这个帖子。
Short answer, check that the POST method is NOT in the filter methods of the CSRF filter config
简短回答,检查 POST 方法是否在 CSRF 过滤器配置的过滤器方法中
http://localhost:4502/system/console/configMgr/com.adobe.granite.csrf.impl.CSRFFilter
http://localhost:4502/system/console/configMgr/com.adobe.granite.csrf.impl.CSRFFilter