in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

This Blog

Syndication

All About SharePoint - S.S. Ahmed - MVP Microsoft SharePoint

All About SharePoint, as the name suggests, is all about SharePoint. It has articles, tutorials, source code, FAQs, and tips about SharePoint, InfoPath, C#, Microsoft Office, SQL Server, XML, etc.

MOSS 2007 and Code Access Security

MOSS 2007 and Code Access Security

Download Sample Custom Policy File

Have you ever written a web part or a web service? If yes then you must have dealt with a security problem. Writing a web part or web service may not be a big issue but deploying them is certainly a headache. You start getting permission errors as soon as you deploy your code on the server. I recently wrote an article demonstrating the web service creation process and I promised in that article that I would write about Code Access Security (CAS) in another article. There are three ways to assign execution permissions to your code:

1. Increase the trust level for the entire virtual server
2. Create a custom policy file for your assemblies
3. Install your assemblies in the GAC

In the article, we installed our assembly in the GAC but the safest method is to create a custom policy file for the assembly. Following article on MSDN contains complete details on code access security:

Microsoft Windows SharePoint Services and Code Access Security

Written in July 2003, this is one of the most comprehensive articles written on "SharePoint and Code Access Security".

For security reasons, the assembly must be installed in the bin directory of the application instead of GAC but installing it in the bin directory requires you to assign execution permissions to the assembly. One way is to increase the trust level of the entire virtual server. This is easy to implement but this option is least secure as it affects all assemblies used by that virtual server. Second way is to create a custom policy file and this is the recommended approach. This option is most secure but difficult to implement. In this article, we will create a custom policy file for an assembly (web service assembly) written for MOSS 2007.

Creating a Custom Policy File

1. Go to the following location on the server:

LocalDrive:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG

2. Make a copy of wss_minimaltrust.config and rename it wss_customtrust.config.

3. Open wss_customtrust.config file using any text editor.

4. Under the <SecurityClasses> element, add a reference to the SharePointPermissions class as follows:

<SecurityClass Name="SharePointPermission" Description="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />

5. Search for the <PermissionSet> tag where the name attribute equals ASP.NET. If you couldn't find that <PermissionSet> tag, locate the one that has SPRestricted in the name attribute.

6. Copy the entire tag and all of its children, and paste a copy of it immediately below the one you copied.

7. Change the name of the PermissionSet element from ASP.NET (or SPRestricted) to CustomTrust.

Before:

<PermissionSet
class="NamedPermissionSet"
version="1"
Name="SPRestricted">

After:

<PermissionSet
class="NamedPermissionSet"
version="1"
Name="CustomTrust">


8. Add the following <IPermission> node to the <PermissionSet> element where the name attribute equals CustomTrust:

<IPermission class="SharePointPermission"
version="1"
ObjectModel="True" />

Therefore, the resulting customized <PermissionSet> will look as follows:

<PermissionSet
class
="NamedPermissionSet"
version
="1"
Name
="CustomTrust"
>

<IPermission
class="AspNetHostingPermission"
version
="1" Level="Minimal"

/>

<IPermission
class="SecurityPermission"
version
="1" Flags="Execution"

/>
<IPermission class="WebPartPermission"
version
="1"
Connections
="True"

/>

<IPermission class="SharePointPermission"
version="1"
ObjectModel="True" />
</
PermissionSet
>

9. Once you define the customized element, you must create a code group to specify when the CLR should apply the permission set. (For details, see the original Microsoft article). Locate <CodeGroup> tag where the class attribute equals FirstMatchCodeGroup and copy following CodeGroup immediately below it:

<CodeGroup class="UnionCodeGroup"
version="1"
PermissionSetName="CustomTrust">
<
IMembershipCondition class="UrlMembershipCondition"
version="1"
Url="$AppDirUrl$/bin/*" />
</
CodeGroup
>

The membership condition for this new code group is based on URL membership and the URL points to the bin directory. The permissions will be applied to all the assemblies in the bin directory of the current application. You can also use strong name membership but then the permissions will  be applied only to one assembly. For example, if I have written a web service and I wanted to assign permissions to my assembly only, I would use strong name membership. Copy following code immediately below the <CodeGroup> tag where the class attribute equals FirstMatchCodeGroup, if you want to use strong name membership:

<CodeGroup class="UnionCodeGroup"
version="1"
PermissionSetName="CustomTrust">
<IMembershipCondition class="StrongNameMembershipCondition"
version="1"
PublicKeyBlob="0x00240000048000009400000006020000002400005253413100040000010001004"
Name="UploadService" />
</CodeGroup>

Replace PublicKeyBlob value with your own value and change the name of the assembly in the Name attribute. Name attribute contains the name of the assembly. To retrieve the public key blob for an assembly, use the secutil.exe tool. Please note that publickeyblob is different from publickeytoken. Secutil.exe is located in the following folder:

LocalDrive:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin

To retrieve the public key blob for your assembly, either copy the secutil.exe tool to the folder that contains your assembly else provide exact path to the assembly in the command, and run the tool as follows:

secutil.exe -hex -s UploadService.dll > blob.txt

UploadService.dll is the name of the assembly. This command will create a text file named blob.txt. Open blob.txt and copy the public key and paste it in the publickeyblob attribute.

10. Save and close the file. The policy file is ready to use.

11. Open the web.config file for the virtual server where you have deployed your component and add the following <trustlevel> tag to the SecurityPolicy element:

 <trustLevel name="WSS_Custom" policyFile="LocalDrive:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\config\wss_customtrust.config" />

Virtual Directories for web applications are located in the following folder:

LocalDrive:\Inetpub\wwwroot\wss\VirtualDirectories

Suppose I want to deploy my web service in the web application configured at port 17316. The URL of that application would be http://localhost:17316/ and its virtual directory will be:

LocalDrive:\Inetpub\wwwroot\wss\VirtualDirectories\17315

Create a bin folder in this path and copy your assembly to the bin folder. The web.config for this virtual server will be located in the following folder:

LocalDrive:\Inetpub\wwwroot\wss\VirtualDirectories\17315

In the web.config file,  change the <trust> tag so that it refers to the newly defined trust level.

<trust level="WSS_Custom" originUrl="" />

12. Save and close the web.config file.

13. Restart IIS to apply the custom policy to the specified virtual server.

Download Sample Custom Policy File

====

Comments:

 

Di niente, di meno, sul mondo dell'informatica.... said:

January 25, 2007 8:20 AM
 

Di niente, di meno, sul mondo dell'informatica.... said:

January 25, 2007 9:49 AM
 

deeptyranjan said:

It will be very much usefull if it will display all the detail and complete structure of MOSS 2007 object model

SharePoint 2007 Object Model

It's very urgent  !!!

If anybody have any Idea Please let me know.
February 8, 2007 3:30 AM
 

Ryan said:

This was very helpful. After following the steps listed in your post I get the following exception when running my application:

"System.IO.FileLoadException: The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)".

Any ideas?

February 9, 2007 2:05 PM
 

ssa said:

Hi Ryan,

Thanks for reading and liking the article. The error you are getting has nothing to do with the code access security. This error occurs when path to your assembly is longer than 255 characters. Make the path shorter to get rid of this error. There are a couple of good links on google that discuss this issue in detail. Here are a couple of links for your convenience:

http://web.archive.org/web/20070514154151/http://kindohm.com/archive/2005/11/10/1167.aspx
http://web.archive.org/web/20070514154151/http://blog.surrealization.com/archive/2005/10/25/5355.aspx

Hope this helps. Let me know if this does not solve your problem.

Good luck

Regards,

SSA
February 10, 2007 2:38 AM
 

Abhishek Agrawal said:

It is very useful and comprehensive article for deploying/developing ASP.NET application in sharepoint
February 13, 2007 5:26 AM
 

Pedro Rainho said:

I have used your Sample Custom Policy File and i have looked at the microsoft site and i'm still having the same problem. i'm doing this in my sample webpart

using (SPSite site = SPControl.GetContextSite(HttpContext.Current))
               {
                   ServerContext context = ServerContext.GetContext(site);
                   SPWeb ferias = site.AllWebs["Ferias"];
                   site.AllowUnsafeUpdates = true;
                   ferias.AllowUnsafeUpdates = true;
                   ferias.Lists.ListsForCurrentUser = true;
                   SPList feriasConfiguracao = ferias.Lists["FeriasConfiguracao"];

                   SPListItem item = feriasConfiguracao.Items.Add();

                   item["Nome"] = "Nome1";

                   item["Valor"] = "Valor1";

                   item.Update();
               }

it's simple insert an item in a list, and the error continues to be:
Request for the permission of type 'Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' failed.

i have simple created a webpart and copy the dll to the bin folder and when i use the web part i receive that error. Any ideas????
February 13, 2007 6:30 AM
 

ssa said:

Thanks Abhishek
February 13, 2007 8:57 AM
 

ssa said:

Pedro!

Did you install the assembly in the GAC?
February 13, 2007 8:58 AM
 

Anders Rask said:

Hi, thanx for the article.

A comment though:

Wouldnt it be better (read more fine grained) to use the assembly name instead of the blob?

Using the blob will give access to all assemblies signed with the same SNK file.

Using the name will give you more control on what assemblies are allowed higher privileges -and IMHO thats what CAS is all about ;-)
February 13, 2007 10:19 AM
 

Anders Rask said:

Ahh sorry, i just saw you specified both blob and assembly name :-D
February 13, 2007 4:26 PM
 

ssa said:

Thanks for commenting Anders! :)

-SSA
February 14, 2007 1:39 AM
 

Pedro Rainho said:

No, i don't want to install in the gac, i want to copy dll to bin directory, install in the gac is't the same as give full trust in the web.config and i don't want that. If i give full trust my webpart works fine but that is not recomended by MS. i just want to create a simple Custom Policy File that runs the example i posted before.
February 19, 2007 9:21 AM
 

Suleman said:

Hi,
Your both articles (MOSS 2007 and Code Access Security & Creating a Custom Web Service for SharePoint ) are really good, the way you described, steps, is simply great.

I'm facing a problem, if you have some solution please let me know and thanks in advance.

I have deployed a simple web service (that returns "Hello world")  on "Server2" then deployed a webpart on "Server1" and call the service from "Server2" it throws an exception "401 Unauthorized ......" when I use Default or Default Network Credentials. e.g.

Web_Ref.PagesList listService = new Web_Ref.PagesList();
listService.Url = siteURL + "/_layouts/KPMGTestService/pageslist.asmx";
listService.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
listService.PreAuthenticate = true;
writer.Write(listService.HelloWorld());

but when I pass userName and password to Network Credentials it works fine. e.g.

System.Net.NetworkCredential ntCred = new System.Net.NetworkCredential("UID", "Pwd", "Domain");
listService.Credentials = ntCred;

My Problem is, I want to use DefaultCredentials or DefaultNetworkCredentials because in my actual webpart somehow i don't wanna impersonate or pass any UID and Pwd etc because i need to check user rights in webservice.

Note: this service works fine if i called it using a Console application.

If you have any Idea, please let me know here in this blog or if you can mail me , that will be great, at suleman.ibrahim@hotmail.com

Once again Thanks.
February 19, 2007 3:56 PM
 

ssa said:

One thing, the line listService.PreAuthenticate = true; should come before the "credentials" line. Like this:

listService.PreAuthenticate = true;
listService.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

Second thing, make sure the login you use for logging in has approp. permissions in SharePoint.
February 20, 2007 4:22 AM
 

ssa said:

Pedro,

Which method of authetication are you using in the custom policy file? the URL method OR the blob method??
February 20, 2007 4:36 AM
 

Suleman said:

Yes, the line listService.PreAuthenticate = true; is come before the "credentials" line. It was just an copy pasting mistake.

I have tried both URL and Blob methods in Custom policy file and after updating file I did IISReset but it doesn't work.

Login, I'm using for logging has Administrator rights on both servers and has site Collection administrator rights on both portals.

One thing more, if I make changes in my service should I create disco and wsdl files again or that is not necessary And what is the imapct of these files cuz I tried my service without these files but result doesn't change wheather I have deployed these files or not.

Thanks for your time.
February 20, 2007 8:37 AM
 

Suleman said:

The problem has been resolved actually we should have to use "Kerberos" Authentication Settings instead of "NTLM", if we wanna access some remote server Services etc. I dont wanna go into details but if anyone wanna know about it, differences between "Kerberos" and "NTLM", can read following article.

Once again thanks for time and comments.

http://web.archive.org/web/20070514154151/http://ablog.apress.com/?p=1127
February 20, 2007 1:48 PM
 

Suleman said:

But, I still wanna know about my last question.

"if I make changes in my service should I create disco and wsdl files again or that is not necessary And what is the imapct of these files cuz I tried my service without these files but result doesn't change wheather I have deployed these files or not."

thanks
February 20, 2007 1:58 PM
 

ssa said:

If there are no major changes then there is no need to recreate wsdl and disco files, your web service will work fine.
February 22, 2007 4:13 AM
 

sireve said:


Hi,

I have a problem with this sentence:

string rol = myweb.RoleDefinitions["admin"].Name;

Webpart "x" seems to be causing a problem .Is not the level of permissions.

Any Ideas?? And Pedro, I have the same problem in other webpart...
Have you got the solution? web.configgg!! :s
thanks
February 22, 2007 12:24 PM
 

ssa said:

Sireve,

What is the error message that you get? Cant tell you the problem without looking at the error first!

Thanks

February 23, 2007 1:57 AM
 

sireve said:

Hi, I said you, sorry I'm not explain,
this is the error:

Webpart "mywebpart" seems to be causing a problem .Is not the level of permissions.
(this is a traslation message, my MOSS is in spanish)

thanks
February 23, 2007 6:13 AM
 

ssa said:

hmm.. i guess the web part tries to access an area in SharePoint for which it does not have permissions. wait a minute! What are you creating? a web part, web service or just an application using the object model?

ssa
February 23, 2007 10:03 AM
 

sireve said:


This is an error webpart. But the objective is to obtain the group/rol to which the user belongs, in my example user "admin".. how I get it??

thanks ssa
February 24, 2007 6:15 AM
 

Paul said:

Great Article!  I was going around in circles for a couple hours befire finding your post.  I walked thru it and presto, my webpart is now showing.  I was getting the same error that Pedro(above) was getting.

(Pedro, in case you haven't resolved your issue.  I believe the key part of the post was to edit the local web.config file and make sure the wss_custom_minimaltrust.config (in my case) has a reference in the security policy section (I'd done most of the edits already, but forgot to tell the local web.config about it ):

<securityPolicy>

<trustLevel name="WSS_Custom" policyFile="C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\CONFIG\wss_custom_minimaltrust.config" />

</securityPolicy>

Thanks again,

Paul

March 25, 2007 8:20 PM
 

ssa said:

Many Thanks Paul!

Regards,

SSA

March 31, 2007 1:08 AM
 

Geo said:

This was very helpful. After following the steps listed in your post I get the following exception when running my application:

The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047).

The only additional part which I am trying to do in my web part is Loading the XML in XMLDocument object using Load method from the local drive.

April 24, 2007 11:06 PM

Comments

 

johnk said:

I have recently installed MOSS 2007 and VS2005 with the Extensions for SharePoint Svcs onto the virtual W2K3 server image provided on MSDN for Virtual PC.

I have written a very simple webpart - it appears the extensions deploy my simple webpart to the GAC - so I am assuming Full Trust.  However, when I try to do any File IO (i.e. read XML file for config) or call a web service to render dynamic data - I receive the dreaded "Request for the permission of type "...." failed.

Any ideas why something in the GAC would cause permission errors?

October 18, 2007 9:28 PM
 

ssa said:

Use the following statement before calling the web service in your code:

listService.PreAuthenticate = true;

listService.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;

and make sure you have permissions on the site where web part or service is deployed. You may also want to look into the elevated privileges.

SSA

October 23, 2007 9:22 AM
 

Brian L said:

thanks! This was really helpful.

Who would have thought it was such a hassle to deploy a simple web part!

November 22, 2007 8:48 AM
 

Roja said:

I done everything as you said.Its working fine in VPC.But when i moved every thing to my Development server i am getting an error Unexpected Error has occured.Could you please help me regarding this

Thanks

Roja

January 13, 2008 2:29 PM
 

Cool Man KUmar said:

I done everything to put webpart in bin as you said.It is working fine in my Virtual PC. But i try the samething  in my server it is shows the following error,

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

January 13, 2008 2:34 PM
 

ssa said:

Are you sure you haven't missed anything during the deployment. To test, you can put the assembly in GAC and try again. If it works then that means there is something wrong with the CAS.

January 13, 2008 3:18 PM
 

Stacey said:

First, thanks for the great blog.

Though the solution didn't seem to work for me out of box, I learned a lot from your 'post'. :-)

I was geting security exceptions when deploying my user control, so I created a custom policy file and could not get it to work correctly.  I ended up with the same error that Ryan mentioned above:

"System.IO.FileLoadException: The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)".

It turned out that if I just set

<trust level="WSS_Medium" originUrl="" />

in the web.config for the MOSS site, my user control executed inside of MOSS with no exceptions.

Thought I would put this solution up here in case it is useful to anyone else.  I spent a few hours figuring all of this out....

January 31, 2008 4:05 PM
 

ssa said:

Dear Stacey

Thanks for your kind words and thanks for sharing your solution with other readers. If you created your own custom policy, that policy would not take effect because you have changed the trust level to medium and now the default medium level policy file would be read. You can also modify the medium level trust file to force tightened security but make you take the back up of the original file before implementing any changes.

Regards

SSA

February 4, 2008 7:51 PM
 

ttrentham said:

I posted this comment over on IT Toolbox, but realized that this is probably better. Sorry for the double post.

've got a web service that I wrote running under its own virtual directory on the same server as MOSS. So it's at IIS->MachineName->Web Sites->SharePoint - 80->MyWebService. When the web service is deployed on a server without SharePoint, it works just fine.

When I call it on the SharePoint server, I'm getting the "assembly does not allow partially trusted callers" SecurityException. I followed the instructions here and went with the UrlMemebershipCondition instead of strong name.

I created the CustomTrust using the instructions here, added the trust level tag to the web.config of MyWebService and did an IISReset.

I still get the error. Either something's not right in my configuration or maybe this still isn't a good enough trust level?

February 7, 2008 4:17 PM
 

ssa said:

ttrentham

There may be a functionality in your assembly that requires a full trust. Did you try full trust?

regards

March 22, 2008 11:12 PM
 

Johan said:

In point 4 of creating a custom policy file says:

<SecurityClass Name="SharePointPermission" Description="Microsoft.SharePoint.Security.SharePointPermission, Microsoft.SharePoint.Security, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c." />

However, the dot at the end of the PublicKeyToken is invalid, causing the following error:

The "xxx" Web Part appears to be causing a problem. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)

April 10, 2008 8:54 AM
 

ssa said:

Johan

Thanks for pointing this out. The dot should not be there.

Regards

SSA

April 27, 2008 7:58 PM
 

Dipin said:

After doing all the required things i am getting a error as given

Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

also to fix this i add the following code in wss custom config file

<SecurityClass

Name="SqlClientPermission"

Description="System.Data.SqlClient.SqlClientPermis sion, System.Data,

Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

In the PermissionSet section of this configuration file, added following:

<IPermission

class="SqlClientPermission" version="1" Unrestricted="true"/>

but i a still getting the error msg, please help me

July 9, 2008 11:24 PM
 

Sandy said:

Thanks for your post :)  Saved me days of work!!!

September 3, 2008 10:29 PM
 

Jad said:

The problem I am facing is a COM DLL being referenced inside of my Sharepoint Sequential Workflow code.  I have tried your changing of web.config approach to no avail.  The DLL was originally under the C:\Windows\System32 and I moved it to \Inetpub\wwwroot\wss\VirtualDirectories\80\bin so it matches $AppDirUrl$/bin/*  but still doesnt work.  What is it that I may be doing wrong here? plese help

September 23, 2008 2:49 PM

Leave a Comment

(required )  
(optional )
(required )  
Add

About ssa

MOSS MVP - Over 8 years experience. 4 years SharePoint experience!

Need SharePoint Training? Attend a SharePoint Bootcamp!

Posts (c) their respective authors. Everything else (c) 2007 SharePoint Experts