Varun K Varun K - 3 months ago 14
ASP.NET (C#) Question

PageParser.GetCompiledPageInstance is throwing a SecurityException – how to fix this?

Background: I have created a custom HttpHandler which executes a particular command based on user posted parameters. Since JQuery Ajax is heavily used in my website, I have adopted content pages approach in which I execute an aspx page containing the content for the container page being viewed by user.
As of now I'm using Godaddy shared hosting and because the site is in its infancy, I cannot go for dedicated/virtual server.

Everything is working fine on my PC, but not on server.
I'm getting this error:


[SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
failed.]
System.Web.UI.PageParser.GetCompiledPageInstance(String virtualPath, String inputFile, HttpContext context) +46
SL.Controller.Commands.CommandHelper.ExecutePage(SLActionInfo actionInfo, String url) +95
SL.Controller.Commands.ProductCommand.Execute(SLActionInfo actionInfo) +32
SL.Controller.CommandFactory.ExecuteCommand(HttpContext context) +224
SL.Controller.DefaultHttpHandler.ProcessRequest(HttpContext context) +20
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
....


Strange thing: Server.Execute(string virtualUrl) is working, but PageParser.GetCompiledPageInstance is not.

Why am I using PageParser.GetCompiledPageInstance and not Server.Execute(string url)? Because of the following code:


public static string ExecutePage(SLActionInfo actionInfo, string url)
{
var context = actionInfo.Context;
var sw = new System.IO.StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
IHttpHandler handler = PageParser.GetCompiledPageInstance(url, context.Server.MapPath(url), context);
if (handler is SL.UI.SLPageBase)
((SL.UI.SLPageBase)handler).ActionInfo = actionInfo;
context.Server.Execute(handler, htw, true);
return sw.ToString();
}


Since my content pages derive from SLPageBase (subclass of Page) that has a property ActionInfo which needs to be set in this ExecutePage method, I'm using PageParser approach.

I don't know how to get rid of this error without breaking my PageParser approach.

Any help will be appreciated.

Answer

I've deviced a workaround for the mentioned problem. It seems that readers of this question have not faced this problem therefore not able to suggest a possible solution. Since people using shared hosting can face this problem and may look for a solution, they can utilize this workaround.

Edit: I've decided not to accept my answer immediately. I look forward for comments on this answer and will decide in a few days time accordingly.

This breaks my PageParser.GetCompiledPageInstance approach, but the impact is minimal and I can easily switch to the original approach when hosting in a full trust environment.

The change is in two places:

1) In the ExecutePage method:

public static string ExecutePage(SLActionInfo actionInfo, string url)
{
    var context = actionInfo.Context;
    var sw = new System.IO.StringWriter();
    HtmlTextWriter htw = new HtmlTextWriter(sw);
    // The original approach is commented out.
    // IHttpHandler handler = PageParser.GetCompiledPageInstance(url, context.Server.MapPath(url), context);
    // if (handler is SL.UI.SLPageBase)
    // ((SL.UI.SLPageBase)handler).ActionInfo = actionInfo;
    // context.Server.Execute(handler, htw, true);

    // The new approach:
    // Add actionInfo to the Items collection so that any page executing in the context of this request can read it.
    Context.Items.Add("SLActionInfo", actionInfo);
    // Now execute the page by providing its url.
    context.Server.Execute(url, htw, true);

    return sw.ToString();
}

2) The other change is within the SLPageBase.ActionInfo property:

public SLActionInfo ActionInfo
{
    get
    {
        return (SLActionInfo)Context.Items["SLActionInfo"];
        // Commented out the old approach.
        // return _actionInfo;
    }
}

You can see how easy it is if I want to revert to the old (and prefered) approach. Just uncommenting a few lines here and commenting a few lines there will do the trick. Rest of the system will remain unimpacted.

Comments