0

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?

Oliver
  • 6,152
  • 2
  • 42
  • 75
  • Aren't the end users members of groups themselves? – Florian Salihovic Jul 08 '14 at 06:54
  • No. They are normal users like a user who access Facebook or any social website. Any Inputs? – Oliver Jul 08 '14 at 07:18
  • What kind of differentiation between the users do you have? A servlet filter might be a good choice to provide a plug-in authorisation mechanism, especially if it's only an edge case. – Florian Salihovic Jul 08 '14 at 07:37
  • @santiagozky : sanitogozy and Florian As per my knowledge an Author is a person who has the ability to perform CRUD(Create/Update/Delete/Edit) Operations in CQ resources. So using CUG an "admin" Author can allow which author has access to which resource. That I understand. But here is a Case where an **End User** is a guy who opens a browser and accesses my website in Publish instance. And he has a absolute link of the file in DAM. If he types it in the browser I should just check if he has logged in my **WebApplication** or not. And then allow to download the file. – Oliver Jul 08 '14 at 09:13
  • An author, in the CQ sense, is an editor who will create a certain type of content in CQ. Users, wether anonymous or not, could create or modify content as well - like in the user generated content. If the users can log into the systems, they are likely put into groups as well which restrict access etc. – Florian Salihovic Jul 08 '14 at 10:03
  • @FlorianSalihovic : I understand Florian, but how would I achieve the above task. I've been stuck on this issue since the time I was born now! :( – Oliver Jul 08 '14 at 10:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/56936/discussion-between-oliver-and-florian-salihovic). – Oliver Jul 08 '14 at 10:08

4 Answers4

1

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.

santiagozky
  • 2,519
  • 22
  • 31
  • So this implementation can be done with CUG as well? Which way of doing it would you recommend? Can you please elaborate on how to do it using CUG? – Oliver Jul 08 '14 at 08:54
  • if your end user is authenticated in CQ, yes, it should work. I actually would do both. write the servlet I described and check their permissions there. In general you want to limit access to /content/dam as much as possible. – santiagozky Jul 08 '14 at 08:57
  • I am a little confused about this. You see in my authentication Servlet all I do is `request.getSession().getAttribute("userId");` I just check if UserId is null or not. **userId is Field in my External database Oracle.** I am no clear as to how would I use CUG to restrict access to a normal person who accesses the DAM byt typing Link in browser. – Oliver Jul 08 '14 at 09:03
  • @Oliver if that is everything you need to check, then just do that :) – santiagozky Jul 08 '14 at 09:05
  • Can you please explain how to use CUG to restrict Non-Author Users(End Users) from accessing content from DAM? Or provide a link at least for the same. – Oliver Jul 08 '14 at 09:05
  • @Oliver here (https://helpx.adobe.com/experience-manager/kb/HowToSetupCUG.html) I'm still not sure about your case, are your users actually CQ5 users or are they authenticated externally (you mentioned oracle) – santiagozky Jul 08 '14 at 09:09
  • :Yes they are authenticated externally with their data in Oracle Database – Oliver Jul 08 '14 at 09:13
  • 2
    then no, AFAIK you cannot use CUG if the users are not CQ5 users. – santiagozky Jul 08 '14 at 09:16
0

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.

0

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 {

    }

}
Oliver
  • 6,152
  • 2
  • 42
  • 75
0

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.

IT Gumby
  • 1,067
  • 8
  • 11