AEM 6.4 HttpContext use case

Image for post
Image for post
Looking for the missing HttpContext service!

Recently, I have been working on migrating an AEM 6.2 instance to AEM 6.4 and of course, I have faced some issues and have been forced to do some modifications to have the website bundles running.

One of the main issues I had was the fact that the one of the bundles registers a servlet, but includes AEM’s default HttpContext in this registration so that we can use the system login when a user was not logged in certain paths defined in the servlet.

Here is where the problem began: It turns out that the HttpContext Service running in AEM 6.2 is not available in AEM 6.3 or 6.4 So there was no other way around than starting to research, test, cry and repeat until I found a solution.

I started by checking the org.osgi.service.http.HttpContext class methods: From the three methods this class has (getMimeType, getResource and handleSecurity) it turns out that the one used to check if a user is logged in is the handleSecurity one. So that’s the one I had to focus.

After some time going in circles, I posted a question in the AEM Forums where they advised me to use ServletContextHelper instead of going for HttpContext. Turns out that AEM 6.4 does have a ServletContextHelper service registered and running, but it’s just its default implementation, which always returns true when calling the handleSecurity method.

So, after some more time researching, I found out that what the 6.2 HttpContext does when calling the handleSecurity method is just using the class org.apache.sling.auth.core.AuthenticationSupport and calling its handleSecurity method! So, after checking in 6.4, it turned out that the AuthenticationSupport service was actually available!

So, after all of that I just had to set up the lego and let it go!
Basically I created a custom HttpContext object implementing the HttpContext interface. I set the object’s constructor to receive a ServletContextHelper and a AuthenticationSupport object.
Basically I use the ServletContextHelper default responses for the getMimeType and getResource methods, and I use the AuthenticationSupport handleSecurity method as follows:

public class MyHttpContextImpl implements HttpContext {
ServletContextHelper myServletContextHelper = null;
AuthenticationSupport myAuthenticationSupport = null;

public MyHttpContextImpl(ServletContextHelper servletContextHelper, AuthenticationSupport authenticationSupport) {
myServletContextHelper = servletContextHelper;
myAuthenticationSupport = authenticationSupport;
}

@Override
public String getMimeType(String name) {
return myServletContextHelper.getMimeType(name);
}

@Override
public URL getResource(String name) {
return myServletContextHelper.getResource(name);
}

@Override
public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
return myAuthenticationSupport.handleSecurity(request, response);
}
}

After that is just a matter of getting the AuthenticationSupport and ServletContextHelper services from the bundleContext, creating a new instance of our HttpContext and registering it as an AEM service:

AuthenticationSupport authenticationSupport = null;
ServiceReference<AuthenticationSupport> authSupportReference = bundleContext.getServiceReference(AuthenticationSupport.class);
if (authSupportReference != null) {
authenticationSupport = bundleContext.getService(authSupportReference);
}
ServletContextHelper servletContextHelper= null;
ServiceReference<ServletContextHelper> servletContextReference = bundleContext.getServiceReference(ServletContextHelper.class);
if (servletContextReference != null) {
servletContextHelper = bundleContext.getService(servletContextReference);
}
ServiceRegistration<HttpContext> httpContextReg = null;
Dictionary<String, Object> httpContextProps = new Hashtable<>();
if (servletContextHelper != null && authenticationSupport != null) {
httpContextReg = bundleContext.registerService(HttpContext.class, new MyHttpContextImpl(servletContextHelper, authenticationSupport), httpContextProps);
}

And that’s it! Now you have your custom HttpContext service you can use on your application!

I hope this helps someone else! I spend quite a few time finding out how to set this up, and there was few reference about this issue.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store