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.