All,
Anyone knows how we can easily resolve the issue "Do not use Sling servlet paths to register servlet" without major changes.This was identified in the code scan.
Does using "sling.servlet.paths.strict" mode help?
I have like 24 servlets
Regards,
Solved! Go to Solution.
Views
Replies
Total Likes
In cases where a servlet is actually tied to a web component on your websites, you can change your servlet to be configured with `sling.servlet.resourceTypes=<resource type of your component>` and then change your front end calls to instead be a URL directly to the component. When your servlet is tied to your component, this is generally advisable, because in a multi-site situation this ensures the path of the request includes the root path of the current site, which allows your service to ensure it's response is contextual to the site.
That said, if you truly have servlets that need to answer on static paths, I think what you can probably do is effectively achieve the same thing as above by adding some `nt:unstructured` nodes to your JCR that have a declared `sling:resourceType` that you can then reference in your servlets (same way as if they were real components).
As an example, say you have a servlet with path /api/myservice right now. In your jcr add:
/content (default AEM folder for content)
-> /api (type: nt:unstructured)
->-> /myservice (type: nt:unstructured, sling:resourceType: "/servlets/abc")
And then in your Servlet, instead of configuring:
`sling.servlet.paths="/api/myservice"`
you have
`sling.servlet.resourceTypes="/servlets/abc"`
This then allows ACL's to be set on the `/content/api/myservice` node to govern access to your servlet, if desired.
NOTE that you'd need to call AEM with the full path `/content/api/mysevice.json` for example, which you can alter in your dispatcher configs (e.g. shorten to /api/myservice) for external use.
Maybe not everything you need, but LMK if this helps.
In cases where a servlet is actually tied to a web component on your websites, you can change your servlet to be configured with `sling.servlet.resourceTypes=<resource type of your component>` and then change your front end calls to instead be a URL directly to the component. When your servlet is tied to your component, this is generally advisable, because in a multi-site situation this ensures the path of the request includes the root path of the current site, which allows your service to ensure it's response is contextual to the site.
That said, if you truly have servlets that need to answer on static paths, I think what you can probably do is effectively achieve the same thing as above by adding some `nt:unstructured` nodes to your JCR that have a declared `sling:resourceType` that you can then reference in your servlets (same way as if they were real components).
As an example, say you have a servlet with path /api/myservice right now. In your jcr add:
/content (default AEM folder for content)
-> /api (type: nt:unstructured)
->-> /myservice (type: nt:unstructured, sling:resourceType: "/servlets/abc")
And then in your Servlet, instead of configuring:
`sling.servlet.paths="/api/myservice"`
you have
`sling.servlet.resourceTypes="/servlets/abc"`
This then allows ACL's to be set on the `/content/api/myservice` node to govern access to your servlet, if desired.
NOTE that you'd need to call AEM with the full path `/content/api/mysevice.json` for example, which you can alter in your dispatcher configs (e.g. shorten to /api/myservice) for external use.
Maybe not everything you need, but LMK if this helps.
Thanks Brett, Kindly assist with below.
1. Is creating a node under /content or elsewhere wise?
2. Any permissions that need to be provided (ACLs)- Re read the comment that acls will need to be provided to the /content/api node for servlet to be accessed
3. The dispatcher currently has allow to /api/myservice, what do you propose we add in there to allow? just /content/api/*? to the filters
4. Does proceeding with "sling.servlet.paths.strict" help resolve the sonar issue you think?https://sling.apache.org/documentation/the-sling-engine/servlets.html#caveats-when-binding-servlets-...
5. Anything wrt method "POST"/"GET" to watch out for? I plan to use this with method POST as well
Marked the answer right cause it helped me implement a clean solution..Thank you once again @BrettBirschbach
1) I dont see any harm creating under /content. You may be able to choose an arbitrary path like /bin or /api at the base level of the JCR, but if you do you'll need additional dispatcher rules to open up that path. However, I dont know off the top of my head if AEM Cloud Service even allows you to add arbitrary paths to the root of the JCR.
2) Probably no ACLs required, since your static paths currently would have no permissions, and there shouldn't be any default "write" permissions to worry about on your publish servers under /content.
3) Yes, but you can address this by shortening the URL via your dispatcher. Or, you can probably also have /api/myservice.json resolve to /content/api/myservice.json by adding an appropriate sling mapping (see /etc/map)
4) That's probably what I would do. Makes things simpler for custom dispatcher configs or sling mappings if everything is under the same root path.
5) If you add a sling mapping to AEM (per the answer to #3 above) you might not need to do anything at all different than what you had before. Otherwise you would need to update your allow to include the parent node structure (e.g. /content or /content/api) as you suggest. I would recommend only allowing GET on any generic rules with a * in the path, and if you need to also allow POST I would recommend only allowing for fully specified (no *) URLs.
6) I dont believe so, as this does not address the core warning regarding the inability for AEM to set ACLs on a servlet request path that doesnt correlate with a JCR path. However, feel free to give it a shot.
Thanks @BrettBirschbach , Have couple questions below but the solution worked on local author, will try with existing dispatcher config plus the /content/api allow rule for GET(*) and POST(no * urls) as you recommend, and update my findings.
also what i implemented is AJAX JS that uses url: "/content/api/test.json" for instance for methods POST & GET .
Node test has sling:resourceType = /bin/xxx/contactus
Servlet has
@Property(name = "sling.servlet.resourceTypes", value = {"/bin/xxx/contactus"})
Agree about ACLs will skip any ACL and evaluate
Will stick to /content path to host nodes for all of the sling servlet paths for the servlets.
I agree i am skeptical that the strict part for servlet paths would resolve the main concern here.
Questions I have- might be silly -
1. Do i really need sling mapping , sorry i missed the point on sling mapping. Is it due to the fact it might cause troubles on publish server? Won't dispatcher filter rules under /content alone work, using GET POST? And do i need to shortern url in dispatcher?
2. Also, is it the org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl
resource.resolver.mapping that needs a mapping like below to resolve,
/api/test.json : /content/api/test.json
AJAX call would be to /api/test.json ? for methods POST and GET.
3. Any security issues you foresee if no permissions are set , where a user can access the URL via browser for both GET/POST?
1) No, you dont need a sling mapping. I was just suggesting it in case you had outside applications calling your URLs that you didnt want to update to a new URL with /content in front of it.
2) This is similar to the sling mapping solution, and works just fine. Generally my teams have preferred to use sling mappings rather than mess with JcrResourceResolverFactoryImpl since that service is so core to AEM that any time it needs to be updated it effectively restarts the entire set of services on AEM and thus results in increased downtime/deployment time.
3) Fundamentally I dont think there's any increased security issues with GET since it's already possible to make GET requests to web pages and such on your website. For POST I would ensure you're allowing only the exact paths that you know accept POST requests, to eliminate any chance of hitting the default AEM servlet that answers POST requests by trying to create a node. This is similar to allowing POSTs for form submissions, except in that case you probably key off of a selector to allow any form post regardless of URL.
Thanks @BrettBirschbach .. this is helpful.
I am trying to do simple sling post based on path and getting an error , would you be able to take a look once
On other note: when you say
"change your front end calls to instead be a URL directly to the component." how would you get the resource url given jcr resource resolver mappings in place to shorten rendered urls in a hrefs, wouldn't this expose /content path without shortening in javascript ajax call.
Thanks again for your help.
Regarding the note part @sreenu539 you could use the map api to get the path. I haven’t checked the code, will do in a few but a suggestion to avoid paths and use res type
Responded to your other thread - hopefully simple solution to ensure your servlet is registered to accept POST requests.
As for the resource URL question, @NitroHazeDev answered that correctly - use the `.map()` function on a ResourceResolver instance to convert/shorten a resource path to what it should look like to the outside world after sling mappings are applied.
[Webinar | AEM GEMs] Looking under the hood - Cloud Manager 2022 | Register: https://adobe.ly/3t4jfgp & Ask Questions related to this Webinar: https://adobe.ly/3O0rdzd
Date &Time: Wednesday, June 15, 2022 - 8 am PDT OR 5 pm CET OR 8.30 pm IST
Speakers: Remus Stratulat & Shankari Panchapakesan
Share this within your Organisation and with your AEM peers!!