Problems with ClientScriptManager.GetWebResourceUrl in MOSS 2007 webparts (anonymous sites)

I have been struggling with some errors when using embedded resources in MOSS web parts.

My web part uses the ClientScriptManager.GetWebResourceUrl method to access an embedded resource. In this case it’s a JavaScript file that is compiled into the assembly.

Code snippet:

protected override void RenderWebPart(HtmlTextWriter output)

{

EnsureChildControls();

ClientScriptManager manager = this.Page.ClientScript;

string jsLibraryUrl = manager.GetWebResourceUrl(this.GetType(), "myresouce...");

string jsLibrary = string.Format("<script type=\"text/javascript\" language=\"JavaScript\" src=\"{0}\"></script>", jsLibraryUrl);

output.Write(jsLibrary);

//rest of code...

}

  • The web part is deployed to the web application’s bin directory by using a SharePoint solution.
  • Code Access Security for the web part’s assembly is set in the solution manifest.
  • My application is accessible by two Security Zones: Default and Internet. The Internet zone has been configured for Anonymous access.

Note: if you don’t know what and how embedded resouces can be used in ASP.NET 2.0 this is a good article from ASPAlliance.com: Embedding Resources in ASP.NET 2.0 Assemblies.

After development testing and deploying the web part on the web application I access the URL by using the Default zone and log in as an administrator. My web part works fine.
Next I log in by using the web application URL that has been extended and configured for anonymous access. Here I run into an error, a blank page is displayed showing just a 403 error.

403 FORBIDDEN

I went into debug mode and put a breakpoint in the CreateChildControls method of the web part. There I found that an exception was being generated by the following line:

string jsLibraryUrl = manager.GetWebResourceUrl(this.GetType(), "myresouce...");

The exception was System.UnauthorizedAccessException.

To resolve this I tried adding Read permissions to the IUSR_computername and the ASPNET users to the /bin directory of my web application. This solved the problem but is not a solution I can use on a production environment. Every time a new SharePoint solution is deployed to the web application the file permissions on the bin directory are reset by SharePoint anyway.

I googled for answers from people having similar problems. On a very nice post by Ryan Rogers about embedded resources there is a comment from someone with the same issue. There is no answer to the comment. Bummer… the problem is exactly the same as mine but no solution :-(

I tried installing the assembly in the GAC and this also solved the problem. As this is not an option for production I continued searching for other solutions.
After some more trial an error with CAS configuration I decided to use the SPSecurity.RunWithElevatedPrivileges method around the code calling the web resource.

Using this in combination with the Impersonate="true" in the SharePointPermission in CAS does it! Not setting the impersonation will raise a security exception when calling RunWithElevatedPrivileges.

This is what I ended up doing:

try

{

  SPSecurity.RunWithElevatedPrivileges(delegate()

{

  ClientScriptManager manager = this.Page.ClientScript;

  jsLibraryUrl = manager.GetWebResourceUrl(this.GetType(), "myresouce...");

});

}

catch (System.Security.SecurityException exc)

{

  System.Diagnostics.Trace.Write(exc.ToString());

}

CAS element:

<IPermission class="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"

UnsafeSaveOnGet="True" AllowUnsafeUpdates="True" ObjectModel="True" version="1" Impersonate="true" />

I’m still wondering if this is the good approach but since no other solution is available for the moment I’m happy with it.
If someone has a better solution I would love to hear about it.


 

Feedback

Posted on 28 December 2007 @ 17:58

I ran into this exact same issue and your solution has been the only one so far that provided a work-around. I am interested to know what greater risks are presented by running the ClientScriptManager code with eleveated priveleges. One change to your solution that worked in my case was to remove the UnsafeSaveOnGet="True" AllowUnsafeUpdates="True" attributes from the CAS element, and the code executed without error. If anyone has more insight to this issue I would be most interested.

Posted on 01 January 2008 @ 14:00

If I have Publishing web under Publishing site, anonymous works great for father (site) and still brings auth dialog for son (web). For other templates, like Team, it works without issues.Breaking the inheritance and explicit defining of anonymous access on son site doesn't help.

Posted on 01 January 2008 @ 16:23

Yehiel:
does your problem with the child level site have something to do with the ClientScriptManager object or is it something general that you are encountering?
If you are having problems with anonymous access unrelated to the ClientScriptManager I can only tell you that on my experience this never was an issue with WCM sites in MOSS.

Katrien

Posted on 18 January 2008 @ 23:36

Hi All:

I googled for Impersonation + Anonymous + Moss + 403 , Came across this thread.

In my case I am having a publishing site, which works fine for anonymous user in LAN (i.e. inside domain) But in case of accessing the pages from Internet (outside domain) it shows Error 403, Forbidden.

In the pages I have used a User control, which interacts with the Pages, document library of MOSS & displays respective links.

It seems this is Permission related error & occurs while executing the following code.

SPFolder objSPFolder = ObjSPWeb.Folders["Pages"];

Following are the attempts for resolution...

1. tried Impersonations with Service account through code.
2. IUSR_Machine & ASPNET Users were granted permission for 'Bin' folder.
3. Used SPSecurity.RunWithElevatedPrivileges

The error still comes

Please let me know if there can be any other solution implemented to solve the issue.

Thanks for you time.

Regards
Fauzi

Posted on 19 January 2008 @ 20:36

Hi Fauzi,
The best method I found to identify a problem with security is to actually debug (if you can reproduce in dev environment).
It also depends on how you have implemented the User control. Have you published the assembly to the local bin or GAC? When putting the assembly in the local bin you must also setup the correct CAS (Code access security) elements.

HTH,
Katrien

Posted on 13 February 2008 @ 19:14

I have a similar problem and solved it for javascript by calling the GetManifestResourceStream, reading the text and writing it to the page as inline javascript:

String javaScript = "";
using (Stream stream = this.GetType().Assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
javaScript = reader.ReadToEnd();

Page.ClientScript.RegisterClientScriptBlock(javaScript.GetType(), resourceName, String.Format("script type=\"text/javascript\"{0}script", javaScript));

This works fine without errors and without having to change any permissions, but I have a control which is part of a library which has embedded images and so I can't use this method.

I could make a second copy of the control which uses the solution above (using the SPSecurity etc.) but I'd prefer not to have two copies of the same control, one for use with Sharepoint and one for use everywhere else.

Posted on 14 February 2008 @ 19:04

Hi Katrien,

I've just spent the whole day with an almost identical problem, but I was working outside of Sharepoint so I had to look for another solution. I eventually resolved it by adding AllowPartiallyTrustedCallersAttribute declaration to my assembly.

I think this would work in your case too?

Microsoft cover this topic here:
http://msdn2.microsoft.com/en-us/library/system.security.allowpartiallytrustedcallersattribute(VS.80).aspx

Posted on 03 December 2008 @ 23:24

Please post your comments:

Name:  
Email (optional): Your email address will not be posted.
URL (optional):
Comments: HTML will be ignored, URLs will be converted to hyperlinks  
Copyright © 2007 Katrien De Graeve.