SharePoint, Code Access Security and the SmartPart

Security is hot these days, and that’s a good thing. But from the developer’s point of view, security can be a bitch sometimes. Code Access Security (CAS for short) is a wonderful and very useful concept, but developers need to know keep CAS in mind if they want their code to run. If you want to learn more about CAS in general, I definitely recommend Maxim Karpov’s article as a starter.

When you’re building SharePoint webparts (and when you’re doing ASP.NET in general), CAS really comes into play because in most scenario’s your code won’t have Full Trust. This means that it can’t do just anything, everything needs to be explicitly granted. For more information about CAS in combination with SharePoint, check out this article on MSDN.

When you’re using the SmartPart for SharePoint (also see my previous post) you’re in a special scenario with three involved parties: SharePoint, the SmartPart and your code. Let’s say you want to create a somewhat advanced user control (to show in the SmartPart) that connects to a web service (or a database), you’ll run into some problems. If you’ve already tried to do that when using the SmartPart, you’ll find the following exception in the Event Log:
Request for the permission of type System.Net.WebPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 failed.

Why do we get that exception? By default, all the code that’s executed in the \BIN folder of the SharePoint site, uses a reduced set of permissions, specified in the web.config file (e.g. WSS_Minimal or WSS_Medium). The permission to connect to a web service (WebPermission) or to connect to a database, is not granted by default. That’s why the code won’t run. To solve this issue, one would think “let’s add that permission for the webpart”. But remember we’re using the SmartPart webpart, so adding permissions won’t help us because the user control code still has does not get the needed permissions. An easy, but drastic solution is to deploy the code to the Global Assembly Cache (GAC). Every assembly in the GAC, runs in Full Trust. Installing the SmartPart in the GAC is easy, during the installation the question is asked whether you want the assembly to be installed in the GAC or not. Deploying the user control’s assembly to the GAC is also quite easy (if your assembly has a strong name of course): drag-and-drop the .dll file to c:\windows\assembly. But there’s only one issue to solve: you’ll notice that once you’ve deployed the user control’s assembly to the GAC (and deleted it from the \BIN folder of course), you’ll get an exception (unable to load). So it seems that the SmartPart does not look in the GAC to load the user control’s assembly. To fix this (last!) problem, you need make some modifications to the web.config file of the SharePoint site: in the “compilation” section you need to add the user control’s assembly:
<compilation batch="false" debug="false">
  <assemblies>
    <add assembly="DropDownNavigationVB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3948f234bbbabe18" />
    </assemblies>
</compilation>

All these steps may be a little bit overwhelming, so let’s summarize and create an example. The example will connect to a web service and fetch some weather information (I’ve used this web service from CapeScience).

  • Step 1: install the SmartPart and make sure you deploy it to the GAC.
  • Step 2: create a new ASP.NET web application that will contain our user control, name it for example WeatherInfo. Add a web reference to the GlobalWeather wsdl and name it WeatherServices for example. Add a new Web User Control to the project and name it WeatherInfo and add a Label control to it. Switch to code view, and type following code in the Page_Load method:
    private void Page_Load(object sender, System.EventArgs e)
    {
        WeatherServices.GlobalWeather gw = new WeatherServices.GlobalWeather();
        Label1.Text = "Temperature in Brussels: " + 
               gw.getWeatherReport("EBBR").temperature.ambient.ToString();
    }
    Because we will have to deploy the user control’s assembly to the GAC, we need to give it a strong name. So generate a public/private key pair, and specify it in the AssemblyKeyFileAttribute in the AssemblyInfo file. (more detailed information about this process can be found here) Additionally you can change the version number specified in the AssemblyInfo file to a fixed version number (e.g. 1.0.0.0), otherwise every build a new version number will be generated. Finally, you can build the project.
  • Step 3: deploy the user control’s assembly. To deploy the WeatherInfo.dll file to the GAC, you can just drag-and-drop it to the c:\windows\assembly directory, or you can use the GACUTIL utility. The WeahterInfo.ascx file needs to be copied for example to the \UserControls folder of the SharePoint site (this is not a default folder, so you need to create it yourself).
  • Step 4: Alter the web.config. As mentioned before you need to alter the web.config of the SharePoint site, so the user control’s assembly can be located in the GAC. To do this, find the compilation section, that looks like this:
    <compilation batch="false" debug="false" />
    and change it to:
    <compilation batch="false" debug="false">
      <assemblies>
        <add assembly="WeatherInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6185e98411448c6a" />
        </assemblies>
    </compilation>
    I use the Reflector tool to read the public key of my assembly (you can copy-and-paste the full assembly name, so you won’t make any typos).
  • Step 5: load the user control in SharePoint. Finally you can add a SmartPart webpart to a SharePoint site, that will load the WeatherInfo control. Set the User Control property to ~\UserControls\WeatherInfo.ascx and click the OK button. If everything went well, you now should be able to see the temperature in Brussels!

To conclude, I’ll repeat one of the first sentences of this post: security can be a bitch sometimes. :-) But we must think about CAS as a good thing. Even the extra steps considered, that need to be taken to get the WeatherInfo webpart running, I still think creating SharePoint webparts with the help of ASP.NET User Controls is a productive approach. But at the same time I’m wondering about how the GAC deployment step can be avoided. Anyone has an idea?

You can download the WeatherInfo solution from the GotDotNet Workspace. In the next post I’ll dive into how you can easily test-drive webparts when using the SmartPart webpart.

15 Comments

  • Jan,

    Of course, it is possible to run User Controls in Bin direcotry without registering anything inside GAC. Just keep in mind that if you want functionality avalable throught different vservers then GAC is good solution!



    I also noticed that you are using Wppackager deployment took way to go. One bug you have in the wppackager.xml file is you pasted short token value not the blob use secutil to retrieve the full strong name blob. I will make a write up on this isse :)



    Stay tune, Maxim



    [www.ipattern.com do you?]

  • Jan,

    Simple solution for the GAC problem will be. 1. Compile everything with the same *.snk file.

    2. Then use C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\SecUtil.exe -hex -s [path_dll]

    3. Add following Code group

    &lt;CodeGroup class=&quot;UnionCodeGroup&quot; version=&quot;1&quot; PermissionSetName=&quot;FullTrust&quot;&gt;

    &lt;IMembershipCondition version=&quot;1&quot; class=&quot;StrongNameMembershipCondition&quot; PublicKeyBlob=&quot;0x0024000004800000940000000602000000240000525341310004000001000100BB20A2F20001218C2100806C4A656705F4220FE7636574B9B8128E0AA44BE734F379B88130A29020D658ED8CFA1B0A0C93094A22144C54476A507FBB5D812C94DD412AB260EED31D99857A53E20200AC9020007D852540DB43C54D5269507DD45181B1B5E6766C9E2FB3DD0C931C2D1B22ADFDCEC8FDB02E423E3D8BBD59C4B9&quot; /&gt;

    &lt;/CodeGroup&gt;

    Right after the following in the WSS_Minimal

    &lt;CodeGroup class=&quot;FirstMatchCodeGroup&quot; version=&quot;1&quot; PermissionSetName=&quot;Nothing&quot;&gt;

    &lt;IMembershipCondition class=&quot;AllMembershipCondition&quot; version=&quot;1&quot; /&gt;



    4. IISRest.exe and you ready to go



    I hope this hepls. Maxim



    BTW. I am working on the second article on CAS which will cover this in some details

    [www.ipattern.com do you?]

  • Hi Jan,



    my .NET skills aren't any good so pardon if the question is somehow trivial. It seems I cannot deploy the DropDownNavigation.dll (or the treeview for that matter) in my \windows\assembly directory. I'm getting an error that states the dll has not a strong (secure?) name (more or less, take into account that the error is in spanish). So I can't go any further. Any help with this?

  • I just follow the instructions to install the SmartPart. I want to try the dropdown navigation example. However, after placing the web part and fill in the path, it returns this error:

    &quot;Error: unable to load ~\UserControls\Dropdownnavigation.ascx

    Details: Request for the permission of type Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c failed.&quot;

    Please please help.

    P.S. I am not a developer. So, please speak it slowly. Thanks a lot.

  • I also recieved the following error when I attempted to deply the DropDownNavigation user control.



    Error: unable to load ~\UserControls\DropDownNavigation.ascx

    Details: Request for the permission of type Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c failed.



    Please Help...

  • Well, that error previously stated:



    Error: unable to load ~\UserControls\DropDownNavigation.ascx

    Details: Error de solicitud de permiso de tipo Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c.



    is the same i was getting. I pretended to solve it by deploying to the GAC (no luck) but it seems that's not the cause of the problem at all.



    Any idea Jan?



    Thx for the good work

  • Hi I have tried Smart Part coupe of times.But every time I get the following error message.Kindly help.



    The &quot;UserControlWebpart&quot; Web Part appears to be causing a problem.



    Web Parts Maintenance Page: If you have permission, you can use this page to temporarily disable Web Parts or remove personal settings. For more information, contact your site administrator.


  • Add control to the web.config of your sharepoint site.



    &lt;SafeControls&gt;

    &lt;SafeControl Assembly=&quot;WeatherInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6185e98411448c6a&quot; Namespace=&quot;WeatherInfo&quot; TypeName=&quot;*&quot; Safe=&quot;True&quot;

    /&gt;

    &lt;/SafeControls&gt;

  • Hi all,
    You can fix this error "
    unable to load ~\UserControls\DropDownNavigation.ascx
    Details: Request for the permission of type Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c failed"

    by modifing your customs policyfile:





    If you still can not fix this, send request to my (hlhamduc@yahoo.com), i will sent to you my customs policy file

  • Great web part!

    In issue i'm having is on a site that is using Forms authentication with anonymous access. Pages that do not have an instances of the smart part load fine. as soon as I drop an instance of the smart part on the page, i get redirected to the site login page.

    It seems to be some type of security issue with the UserControls folder, but I have not been able to figure it out. Anyone else out there using the smartpart with anonymous access??

    Thanks!

  • I am stuck in am major issue.

    I have a development virtual server with Ms VS 2003 and wss, after completion of code , now I have migrated this site to another virtual server which has only wss.

    I am able to access normal webparts . But those webparts with Data Grids Excel exports are not able to work.

    If I give anonymous access to the wss and iss, if can show these webparts also.

    What configuration issues is causing this problem??

    Please advise

  • Stupore! ho una sensibilit molto buona circa il vostro luogo!!!!

  • Lucy! Please call me,Lucy! Please call me

  • Why is it that the web part that I wrote to host a user control cannot recognize ~\UserControls\ unless I run page with smartpart on it first. Do you have code that sets the ~\UserControls\ directory somehow to be recognized by sharepoint ? I get this message,

    Error: unable to load ~\UserControls\UCContestEntry.ascx
    Details: Request failed.

    but it does work if I use a page with smartpart on it before I use this page. Thanks!

  • Thanks Jan!
    For such useful SmartPart articles.
    I too faced the similar security issues when i tired to access
    the List and doc. Lib. features through my user controls.
    But it was sorted out when deployed in GAC and referred in web.config tag.

    Thanks a lot!

Comments have been disabled for this content.