Full trust proxies in SharePoint 2010

23 May

Because a sandboxed solution is completely isolated to its site collection only a subset of the Microsoft.SharePoint object model can be used. Only objects that operate within the current site collection are available to you, when you are building a sandboxed solution. 

Sandboxed solutions run within a special process, the Sandbox Worker Process (SPUCWorkerProcess.exe). The sandbox worker process makes sure the artifacts from the solution can be used as though they were deployed to the server itself and it will enforce the limits of a Code Access Security (CAS) policy on the contents of the solution. The following permissions will be granted to the solution by the CAS policy: 

  • SharePointPermission.ObjectModel
  • SecurityPermission.Execution
  • AspNetHostingPermission.Level = Minimal

Ofcourse you need some more functionality from time to time. Here the full trust proxy solution comes in handy. 

A Proxy Class has to be deployed at Farm level and can be used by everybody within the farm.
The full trust proxy solution exists of two classes:
The first class inherits from SPProxyOperation, the second class inherits from SPProxyOperationArgs.
Both of these are located in the Micorosft.SharePoint.UserCode namespace.
The class which inherits from SPProxyOperation implements the actual operation the full trust proxy solution has to perform.
The class which inherits from SPProxyOperationArgs defines the arguments which will be passed to the operation. 

Let’s make an very simple application to write a message to an eventlog. First we’ll need a full trust proxy solution to write to the event log, second a sandboxed solution (webpart) which will tell what message the full trust proxy actually has to write. 

Full trust proxy solution

First define a class which inherits from the SPProxyOperationArgs: 

[assembly: AllowPartiallyTrustedCallers]
namespace FullTrustProxyProject1
{
    [Serializable]
    public class EventLogArgs : SPProxyOperationArgs
    {
        public string LogMessage { get; set; }
        public string LogApplication { get; set; }
        public string LogLevel { get; set; } 

        public EventLogArgs(string logMessage, string logApplication, string logLevel)
        {
            this.LogMessage = logMessage;
            this.LogApplication = logApplication;
            this.LogLevel = logLevel;
        }
    }

As you can see this is just a class to define arguments which will be passed to the proxy operation. The class has to be Serializable and AllowPartiallyTrustedCallers has to be set, because the class is going to be used between Trust Domains. 

Next the operation of the full trust proxy, the receiver of the SPProxyOperationArgs: 

namespace FullTrustProxyProject1
{
    public class EventLogItemCreateOperation : SPProxyOperation
    {
        public override object Execute(SPProxyOperationArgs args)
        {
            if (args != null)
            {
                try
                {
                    EventLogArgs arguments = args as EventLogArgs;
                    string result = SPLogger.AddEventLogEntry(arguments.LogApplication, arguments.LogLevel, arguments.LogMessage);
                    return result;
                }
                catch (Exception ex)
                { 

                    return ex.ToString();
                }
            }
            else
            {
                return null;
            }
        }
    }

In this class the Execute method is overridden and a check is performed for the incoming args. The args are then parsed to EventLogArgs and you can access the public properties of the EventLogArgs. The Execute method returns an object.
That’s all! 

Register the full trust proxy

 After implementation of these two classes the proxy has to be registered at the User Code Service in SharePoint. To do this you can use PowerShell or the Object Model.
I just made a simple Windows Forms application to register, unregister and list the registered proxies:
Register:
            SPUserCodeService service = SPUserCodeService.Local;
            if (service != null)
            {
                SPProxyOperationType getEventLogItemCreationOperation = new SPProxyOperationType(“FullTrustProxyProject1, version=1.0.0.0, Culture=neutral, PublicKeyToken=db3652199d4628cd”, “FullTrustProxyProject1.EventLogItemCreateOperation”);
                service.ProxyOperationTypes.Add(getEventLogItemCreationOperation);
                service.Update();
                label1.Text = “Updated successfully!”;
            }
            else
            {
                label1.Text = “Update failed!”;
            } 

Unregister:
            SPUserCodeService service = SPUserCodeService.Local;
            if (service != null)
            {
                SPProxyOperationType getEventLogItemCreationOperation = new SPProxyOperationType(“FullTrustProxyProject1, version=1.0.0.0, Culture=neutral, PublicKeyToken=db3652199d4628cd”, “FullTrustProxyProject1.EventLogItemCreateOperation”);
                service.ProxyOperationTypes.Remove(getEventLogItemCreationOperation);
                service.Update();
                label3.Text = “Removed succesfully!”;
            }
            else
            {
                label3.Text = “Remove failed!”;
            } 

And list all registered proxies:
            SPUserCodeService service = SPUserCodeService.Local;
            if (service != null)
            {
                int count = service.ProxyOperationTypes.Count;
                label2.Text = “Proxy count: ” + count.ToString() + Environment.NewLine ;
                foreach (SPProxyOperationType item in service.ProxyOperationTypes)
                {
                    label2.Text += “AssemblyName: ” + item.AssemblyName + Environment.NewLine + “TypeName: ” + item.TypeName + Environment.NewLine;
                }
            }
 

Create the sandboxed solution

After deploying and registering the full trust proxy it can be used in a sandboxed solution:
Just create a webpart as you normally do, make sure this is a sandboxed solution. Create some controls, e.g.:

At the button click event all you have to do is:
EventLogArgs args = new EventLogArgs(box.Text, app.Text, logLevels.SelectedValue);
results.Text = SPUtility.ExecuteRegisteredProxyOperation(“FullTrustProxyProject1, version=1.0.0.0, Culture=neutral, PublicKeyToken=db3652199d4628cd”, “FullTrustProxyProject1.EventLogItemCreateOperation”, args).ToString(); 

Keep in mind!

Keep in mind that the full trust proxy runs under another process than the sandboxed solution. So if you want to debug the full trust proxy attach the SPUCWorkerProcessProxy.exe, do you want to debug the sandboxed solution, attach the SPUCWorkerProcess.exe.
When you redeploy your full trust proxy solution you have to restart the User Code Service because that’s where the full trust proxy is registered, don’t forget! I did…
To restart go to the Central Administration, Application Management, Manage services on server and find the Microsoft SharePoint Foundation Sandboxed Code Service. Stop and start this service again. Another option is to use “net stop SPUserCodeV4”, and start it again by using “net start SPUserCodeV4”.

27 Replies to “Full trust proxies in SharePoint 2010

  1. Pingback: Tweets die vermelden Full trust proxies in SharePoint 2010 -- Topsy.com

  2. What a blogpost!! Very informative and easy to understand. Looking for more such posts!! Do you have a myspace?
    I recommended it on digg. The only thing that it’s missing is a bit of new design. However thank you for this information.

  3. Excellent article my friend. This is exactly what I’ve been looking for for quite a time now. You have my gratitude man.

  4. There are always 2 sides of the same coin, but I must say, I am learning a lot from your site. Sometimes others have very limited mindset, that’s why they fail to understand the others.

  5. Your site has helped me a lot to bring back more confidence in myself. Thanks! Ive recommended it to my friends as well.

  6. Excellent blog! I definitely love how it is easy on my eyes and also the facts are well written. I am wondering how I might be notified whenever a new post has been made. I have subscribed to your rss feed which should do the trick! Have a nice day!

  7. Reading your article I have stumbled upon solutions for some questions that have been troubling me for some time now. Its hard to find reader friendly texts on the internet as many those articles are created by a person with little interest in the subject. Your text is professional and definitively worth reading. I’ll be back to read more of your texts in few days.

  8. I am always searching online for articles that can help me. Looking forward to another great blog. Good luck to the author! all the best,keep up the good work

  9. Reading your article really helped me with my problem. I want to thank you for writing this article.

  10. Incredible, that is precisely what I was seeking for! You just spared me alot of looking around

    I’ll make certain to put this in good use!

  11. I can only repeat the other comments above this one. Exceptional content and i think im not alone when i ask: do you plan to upload some more pictures on this topic by any chance? It would make this page more enjoyable. Just a thought, i hope you dont mind 🙂 Thanks for the great post, Jennifer

  12. This post is great. Thank you for this post. I like this type of people who share knowledge with others.

  13. This Blog was most helpful, your ideas are straight to the point, and the colors are cool too.

Comments are closed.