AEM - Servlet resource cannot be found - servlets

I'm new to AEM and have been trying to connect to a servlet on an AEM project package which I installed on a new AEM instance.
It seems as if servlet cannot be found or the path cannot be found for the servlet and have double checked the mapping but am lost to what else I can look at. Any help would be greatly appreciated!
Sling Mapping
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="sling:Mapping"
sling:internalRedirect="content/dam/test.$1.json"
sling:match="aem.test.com.4545/api/assets/v1/(.*)"/>
Servlet Information
`#Component(service = Servlet.class,
property = {
Constants.SERVICE_DESCRIPTION + "=Get Job Folder Info API",
"sling.servlet.methods=" + HttpConstants.METHOD_POST,
"sling.servlet.resourceTypes=" + "sling/servlet/default",
"sling.servlet.selectors=" + "jobFolderInfo",
"sling.servlet.extensions=" + APIConstants.JSON_EXTENSION_TYPE
})
public class JobFolderInfoServlet extends SlingAllMethodsServlet {`
Error log from request
0 TIMER_START{Request Processing}
1 COMMENT timer_end format is {<elapsed microseconds>,<timer name>} <optional message>
6 LOG Method=POST, PathInfo=null
7 TIMER_START{handleSecurity}
1645 TIMER_END{1636,handleSecurity} authenticator org.apache.sling.auth.core.impl.SlingAuthenticator#5f62558d returns true
1876 TIMER_START{ResourceResolution}
3112 TIMER_END{1234,ResourceResolution} URI=/api/assets/v1/jobFolderInfo resolves to Resource=NonExistingResource, path=/apps/content/dam/test.jobFolderInfo.json
3119 LOG Resource Path Info: SlingRequestPathInfo: path='/apps/content/dam/test.jobFolderInfo.json', selectorString='jobFolderInfo', extension='json', suffix='null'
3119 TIMER_START{ServletResolution}
3122 TIMER_START{resolveServlet(/apps/content/dam/test.jobFolderInfo.json)}
3853 TIMER_END{730,resolveServlet(/apps/content/dam/test.jobFolderInfo.json)} Using servlet com.test.assets.api.servlets.JobFolderInfoServlet
3856 TIMER_END{736,ServletResolution} URI=/api/assets/v1/jobFolderInfo handled by Servlet=com.test.assets.api.servlets.JobFolderInfoServlet
3860 LOG Applying Requestfilters
3864 LOG Calling filter: com.adobe.granite.resourceresolverhelper.impl.ResourceResolverHelperImpl

If my understanding is correct then you are trying to connect to the servlet using the url like localhost:4502/bin/your-servlet-path from a browser. If that is the case then register the servlet by using path. In the above servlet code you have registered using resource type.
To register using path use sling.servlet.paths=/bin/your-servlet-path
Here is a link that will help you understand registering servlet better.
Hope this helps!!!

It's recommended to register a servlet on a resourceType rather than on a path to be able to restrict access to your servlet.
https://helpx.adobe.com/experience-manager/using/resourcetypes.html
SlingServlet(methods = {"GET"},
metatype = true,
resourceTypes = {"services/powerproxy"},
selectors = {"groups"})
public class HandleClaim extends org.apache.sling.api.servlets.SlingAllMethodsServlet

Related

Symfony VichUploaderBundle autowiring on DownloadHandler in a controller

I'm using Symfony 4 with VichUploaderBundle 1.9 and I'm having hard time injecting the DownloadHandler service in my controller in order to send file to the client.
I'm also using HashidsBundle in order to convert my entity ID to something like jFaJ in my URLs.
As stated in the VichUploaderBundle documentation, I'm injecting the service in my controller like this :
public function download(Wallpaper $wallpaper, DownloadHandler $downloadHandler)
{
return $downloadHandler->downloadObject($wallpaper->getMedia(), 'uploadedFile');
}
Here is the error I'm having:
Argument 2 passed to App\Controller\WallpapersController::download()
must be an instance of Vich\UploaderBundle\Handler\DownloadHandler,
integer given, called in
/mnt/c/Users/user/Documents/Dev/symfony/vendor/symfony/http-kernel/HttpKernel.php
on line 151
I also tried to manually call the service by adding the following line in my controller:
$this->get('vich_uploader.download_handler');
But it's still not working, I have this error now:
Service "vich_uploader.download_handler" not found: even though it exists in the app's container, the container inside "App\Controller\WallpapersController" is a smaller service locator that only knows about the "doctrine", "form.factory", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "serializer", "session" and "twig" services. Try using dependency injection instead.
You can return the file using BinaryFileResponse.
public function download(Wallpaper $wallpaper): BinaryFileResponse
{
$file = new BinaryFileResponse($wallpaper->getMedia());
return $file;
}
For more info, check
https://github.com/aythanztdev/prbtcnccd/blob/master/src/Controller/MediaObject/ShowMediaObjectAction.php

How to create a WebClient-object in a spring application with oauth2

I'm developing a spring application (client) that is secured with an OAuth2 provider. This application should do some REST calls to another spring application (resource server). For performing the REST calls, I will use spring's WebClient.
I therefore try to create a bean of type WebClient as can be found in several blogs.
#Configuration
public class AppConfig {
#Bean
public WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations,
new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
oauth.setDefaultClientRegistrationId("myprovider");
return WebClient.builder().filter(oauth).build();
}
}
When starting the application, I get the following error:
The following candidates were found but could not be injected:
- Bean method 'clientRegistrationRepository' in 'ReactiveOAuth2ClientAutoConfiguration' not loaded because NoneNestedConditions 1 matched 0 did not; NestedCondition on ReactiveOAuth2ClientAutoConfiguration.NonServletApplicationCondition.ServletApplicationCondition found 'session' scope
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository' in your configuration.
As several websites recommend exactly this code for generating a WebClient instance when using OAuth2 authentication, I'm wondering what I'm doing wrong?
Do you have any suggestions for me?
Thanks.
I got the same issue. I changed the code as provided in the video : https://www.youtube.com/watch?v=1N-xwmoN83w&t=1569s and that worked
#Bean
public WebClient webClient(ClientRegistrationRepository clientRegistrationRepository , OAuth2AuthorizedClientRepository authorizedClientRepository) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth =
new ServletOAuth2AuthorizedClientExchangeFilterFunction (clientRegistrationRepository , authorizedClientRepository);
return WebClient.builder().apply(oauth.oauth2Configuration()).build();
}
Hope that helps.

StrictHttpFirewall in spring security 4.2 vs spring MVC #MatrixVariable

Having upgraded to spring security 4.2.4 I discovered that StrictHttpFirewall is now the default.
Unfortunately it doesn't play well with spring MVC #MatrixVariable since ";" are not allowed anymore.
How to get around that?
Example:
#GetMapping(path = "/{param}")
public void example(#PathVariable String param,
#MatrixVariable Map<String, String> matrix) {
//...
}
This could be called like this:
mockMvc.perform(get("/someparam;key=value"))
And the matrix map would be populated.
Now spring security blocks it.
org.springframework.security.web.firewall.RequestRejectedException: The request was rejected because the URL contained a potentially malicious String ";"
at org.springframework.security.web.firewall.StrictHttpFirewall.rejectedBlacklistedUrls(StrictHttpFirewall.java:140)
I could use a custom HttpFirewall that would allow semicolons.
Is there a way to use #MatrixVariable without using forbidden characters?
BTW: the javadoc is incorrect https://docs.spring.io/autorepo/docs/spring-security/4.2.x/apidocs/index.html?org/springframework/security/web/firewall/StrictHttpFirewall.html
Since:
5.0.1
I guess it was backported?
You can dilute the default spring security firewall using your custom defined instance of StrictHttpFirewall (at your own risk)
#Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
firewall.setAllowSemicolon(true);
return firewall;
}
And then use this custom firewall bean in WebSecurity (Spring boot does not need this change)
#Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
// #formatter:off
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
...
}
That shall work with Spring Security 4.2.4+, but of-course that brings some risks!
As mentioned by Крис in a comment if you prefer to use a XML approach, you can add the following part to your securityContext.xml (or whatever your spring-security related xml-config is called):
<bean id="allowSemicolonHttpFirewall"
class="org.springframework.security.web.firewall.StrictHttpFirewall">
<property name="allowSemicolon" value="true"/>
</bean>
<security:http-firewall ref="allowSemicolonHttpFirewall"/>
The <bean> part defines a new StrictHttpFirewall bean with the id allowSemicolonHttpFirewall which is then set as default http-firewall in the <security> tag by referencing the id.
I used combination of following two
https://stackoverflow.com/a/48636757/6780127
https://stackoverflow.com/a/30539991/6780127
First one resolved the
The request was rejected because the URL contained a potentially malicious String ";"
Second one Resolved the
Spring MVC Missing matrix variable
As I am using Spring Security with Spring Web I had to do both And the issue is now Resolved.
I found using #MatrixVariable Following Pattern is useful. First in Url {num} has to be mentioned to use it as #MatrixVariable
#RequestMapping(method = RequestMethod.GET,value = "/test{num}")
#ResponseBody
public ResponseEntity<String> getDetail(#MatrixVariable String num){
return new ResponseEntity<>("test"+num, HttpStatus.OK);
}

Customize HTTP codes and error message in JBoss AS 7

can anyone tell me how i can customize http codes and reasonphrase in JBoss AS 7?
basically i have a REST webservice that returns a nonstandard status code '499' with reasonphrase 'app error'
In standalone.xml, I set the org.apache.coyote.Constants.USE_CUSTOM_STATUS_MSG_IN_HEADER to true under systemproperties, but AS still overrides the HTTP error message.
There seems to be a mistake in JBoss documentation, the correct property name is:
org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER
So in the standalone you should have something like this:
<system-properties>
<property name="org.apache.coyote.USE_CUSTOM_STATUS_MSG_IN_HEADER" value="true"/>
</system-properties>
I assume that the REST service is interpretted using RestEasy.
That provides a nice feature of injecting a HTTP response object using #Context:
The #Context annotation allows you to inject instances of javax.ws.rs.core.HttpHeaders, javax.ws.rs.core.UriInfo, javax.ws.rs.core.Request, javax.servlet.HttpServletRequest, javax.servlet.HttpServletResponse, javax.servlet.ServletConfig, javax.servlet.ServletContext, and javax.ws.rs.core.SecurityContext objects.
#Path("/")
public class MyService {
#Context org.jboss.resteasy.spi.HttpResponse response;
#GET #Path("/") public void myMethod(){
response.sendError(499, "The file was censored by NSA.")
}
}
But maybe you should rather consider using a proprietary HTTP header:
response.getOutputHeaders().putSingle("X-MyApp-Error",
"499 Our server is down and admin is on holiday. Mañana.");

Accessing services directory when setting up Zend AMF in Codeigniter

I followed the instructions in this tutorial to set up Zend AMF as a way of passing data from my flash app to my PHP app:
http://codeigniter.com/forums/viewthread/180414/
So I have the directory structure and everything as described there. This is my gateway controller:
class Gateway extends CI_Controller
{
function __construct()
{
parent::__construct();
$this->load->library('zend');
//root_folder + application + controllers + amf + services
define('SERVICES_FOLDER', APPPATH.'controllers/amf/services/');
}
public function index()
{
$server = new Zend_Amf_Server();
$server->setProduction(false);
//$server->addFunction('testservice');
$server->addDirectory(SERVICES_FOLDER);
echo $server->handle();
}
}
And the APPPATH is /application/ so the path defined by SERVIES_FOLDER is "/application/controllers/amf/services" which is where my file 'testservice.php' sits.
When I try and connect to that service in flash:
var gateway:String = "http://mysite.com/amf/gateway";
con.connect(gateway);
con.call("Testservice.getMessage", new Responder(onResult, onFault));
It calls the onFault method and displays the error:
Plugin by name 'Testservice' was not found in the registry;
Which makes me think that the addDirectory() line in Gateway.php was the problem somehow. Interestingly, I also cannot access the testservice function through a URL, ie by going to mysite.com/amf/services/testservice.
Any thoughts on what might be going on here?
Figured it out, sort of.
Instead of using the addDirectory method which I was having no luck with, I used the setClass method and created another class within the gateway.php file that has the functions, and now I can connect to those functions from flash.
I had an issue with this when using parent::__construct() in my service controllers. Once I removed that, the problem went away.

Resources