Override AccessDenied

 

Hi!

I have a problem where editors may add links to pages in the text editor. When the page is not accessible for the current user and that user attempts to follow the link an exception is thrown.

I tried overriding the AccessDenied Method in my template but it won´t fire, not even the PreInit method is run so my only option that seems to be working is using Application_Error in global.asax. However, this doesn´t seem like the proper way to go. Any suggestions for a better solution?

protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError().GetBaseException();
if (ex is AccessDeniedException)

(I´ve tried the suggestions in the thread below)

http://world.episerver.com/modules/forum/pages/thread.aspx?id=36172

#62955 Nov 06, 2012 8:39
  • adam.jenkin
    Member since: 2011
     

    I had this issue recently. I started to do that same thing as you (catching exception in global) but was not entirely satisfied with the solution.

    When I looked more closely at the stack trace of where the error was being thrown, it was within my own code so rather than catching the error at a high level, I caught the exception at the point it was occurring and let it fail more gracefully.

    In my instance, my error was being generated from the breadcrumb (same code as alloy tech) as the visitor did not have access to some of the parent pages that made up the breadcrumb.

     

    #62958 Nov 06, 2012 9:38
  •  

    Thanks for your advice!

    Unfortunately I cannot find any code that would trigger the exception. I tried creating an empty epi-page from an empty template which yielded the same results.

    I seem to be stuck with ol´ Application_Error...

    #63000 Nov 06, 2012 18:09
  •  

    I have a similar issue.  I want links that the user does not have access rights for to be invisible to them.  E.g. An editor adds a text block on a composer page and adds 5 links to EPiServer pages there. An end user has access to 4 of the pages represented by those links and no access to the 5th link's page .  Right now, all 5 links are visible to the end user and when he clicks on the 5th link, he gets an access deined message.  What we want is that the 5th link is not displayed at all to the user.  They should only see links for pages that they have rights for.  How do we accomplish this?

     

    TIA,

    Steve Shier

    #64419 Dec 20, 2012 11:18
  • adam.jenkin
    Member since: 2011
     

    Steve,

    I think the biggest issue is that the links are likely embeded within a XhtmlString property. If you were to use a LinkItemCollection, you could easily cast the pages to a PageDataCollection and run through one of EPiServer filters to remove pages the user does not access to before renderinfg to the page.

    Parsing the links in a XhtmlString is possible but would be a little painfull as you would need to find them and then do the ACL checks on them.

    I would be tempted to use personalization and show only the text with embeded links to the correct visitors that way.

    Adam

     

     

    #64421 Dec 20, 2012 11:54
  •  

    Thanks Adam.  I see the complication of the XhtmlString property filtering.  Part of the issue is that we have a great number of links using XhtmlString already and it would be a very large effort to switch those links to be in LinkItemCollections. 

    I am surprised that EPiServer does not already handle this for all methods of putting links on pages. They could certainly detect links in XhtmlStrings and display them based on the user's ACL. In many cases developers don't want users to even see the text used in a link because it represents a security breach. I believe that links where the user does not have access should either be invisible in EPiServer or at least configurable to be visible or not based on access rights.  Since that is not the case we will need to handle it as you suggest.

    If I understand correctly, it looks like we would need to parse the content in the XhtmlStrings on each page of the site perhaps in a Page_Load event, checking only for links that were on the EPiServer site as opposed to external, publicly available links.  Then we would need to remove the links from the XhtmlString where the user lacks read rights and then let the page render.  Is that correct?

     

    Steve

    #64425 Dec 20, 2012 13:17
  • Johan Petersson
    Member since: 2007
     

    If you want to go that path I would recommend building a http module and parse all links, or hook into the url rewriter and check all the links there. But I think that would be an odd solution and maybe important information would be left out in the middle of a text block.

    A much nicer solution is to override AccessDenied() in a base class and check if the page is inaccessible and redirect to a 404 (or similar) page.

    This code redirects the user to the 404 page when the page is unpublished and the login page when the access rights is insufficient.

    public override void AccessDenied()
    {
        if (CurrentPage.StopPublish <= DateTime.Now)
        {
            Response.Status = "404 Not Found";
            Response.StatusCode = 404;
            Response.End();
        }
    
        base.AccessDenied();
    }

        

    #64823 Jan 10, 2013 17:21