Reputation: 6250
Please understand that when I say Restricted access, I am not restricting the Authors, but the End Users of my Website. So please don't tell me about the CUG(Closed User groups).
I am making a CQ5 website in which when a user(End User) logs in, there is a link on homepage <a Href="xxx"> Download</a>
and xxx is the the path of a file present in the DAM.
Whenever the User(End User not Authors) clicks on download he/she is able to donwload the file.
What I want is that whenever the User clicks on the above link it should validate if the User is logged in my website or not and then allow the User to download the file.
One way of doing this is I write a Servlet and map the above link to Servlet and in doGet of servlet Authenticate the user and allow document download. But here I am not making any use of the RESTful nature of CQ5.
Is there a way, like I write a Authentication Servlet or Filter for a particular Folder in DAM that acts as an Authentication Filter or something ? Am I even making sense? Is this possible or are there any alternatives for this? What does CQ recommend?
Upvotes: 0
Views: 2645
Reputation: 1077
in your filter, use
WCMMode.fromRequest(req)
to determine if the mode is WCMMode.DISABLED (the mode on publish instances). If not DISABLED, then ignore. (in other words, you want your filter to only execute on requests that are WCMMode.DISABLED - let authors/admins/etc free regin on your author instances (EDIT/DESIGN/PREVIEW). It is possible to have DISABLED requests on author instances, but you WANT those to behave exactly like publish instances - and maybe want the PREVIEW mode to also behave the same.
Upvotes: 0
Reputation: 6250
I solved it with a work around. But this has problems.
I wrote a sling filter and mapped it to the folder I wanted to restrict access, so if anyone calls for that folder or any sub-folder/file the request passes through my Filter.
In my filter I check if user has logged in or not. But the problem that now appears is that anybody who wants to access this folder must log into my Application, with which the session gets set. And the Admin(CQ main Author can't access the folder itself.)
The Admin has to stop my bundle(the one with above mentioned filter) and then access the DAM folder as the Filter in the Bundle prevents the CQ Admin to access the DAM. Any quick solutions?
Code:
package com.xxx.hiresite.filters;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
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.SlingFilter;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SlingFilter(order = -1000)
@Properties({
@Property(name="service.pid", value="com.xxx.hiresite.filters.DAMAccessFilter",propertyPrivate=false),
@Property(name="service.description",value="DAM Documents Authentication Filter", propertyPrivate=false),
@Property(name="service.vendor",value="Zensar Tech", propertyPrivate=false),
@Property(name="pattern",value="/content/dam/xxxdocuments/.*", propertyPrivate=false)
})
public class DAMAccessFilter implements Filter{
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Reference
protected ResourceResolverFactory resolverFactory;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// Authentication Filter for the whole application
log.info("DAMAccessFilter Invoked***************************");
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
String path =httpServletRequest.getRequestURI();
log.info("Request URI ::"+path);
HttpSession session = httpServletRequest.getSession(false);
if(session ==null || session.getAttribute("userId")==null)
{
log.info("DAMAccessFilter :: Not Logged in");
HttpServletResponse httpResponse = (HttpServletResponse)response;
httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN);
}
else
{
log.info("DAMAccessFilter :: Logged in");
chain.doFilter(request, response);
log.info("DAMAccessFilter Done");
}
}
public void init(FilterConfig config) throws ServletException {
}
}
Upvotes: 0
Reputation: 47
As you want to use sling feature for this, go ahead with FilterChain. Use Authentication Blocking request based on user identity. In your filter you could use logic -- use variable with value as "Authenticated". When you do login, with your user name and pass send an additional variable with value as "Authenticated" ( which shows your user is not a guest). In your filter check this condition.
Upvotes: 0
Reputation: 2539
You create under your download page a node with a resourceType (ie. app/components/downloaditem
) and a property fileReference
pointing to the asset in /content/dam
. Then write a servlet that respond to that resourceType where you decide with whatever logic you want if the file can be delivered to the user, if permitted, you deliver the file (write it into the response), if not return a 403.
at the end the download link wont be to /content/dam/asset1
but /content/web/downloads/downloadResource
You can even leverage the download component (or one that inherits it) so the editor can easily select a file for a particular download, just register the servlet with that resourceType.
Additionally this allows you to block access to /content/dam, which you probably should be doing anyway.
Out of curiosity, why dont you want to use CUG? Authenticated end users are CQ users as much as editors.
Upvotes: 1