![]() |
|
Spaces home Daniel Larson's Develope...ProfileFriendsFilesMore ![]() | ![]() |
|
Daniel Larson's Developer BlogBlogging when I should be working (ramblings on SharePoint, ASP.NET, C#, and ajax)
July 23 KB: When is the SPContext.Current available ? (SharePoint dev)We always assumed wherever you have an HTTP Context (i.e., wherever SPContext.Current is not null), that you could access the SharePoint context through SPContext.Current. This was the case with MOSS 2007 RTM and SP1, but this changed with the recent Infrastructure Update. The following update to when SPContext is supported has been confirmed by Microsoft PSS. (Props to Nishand for confirming this behavior change.) Prior to the IHttpHandler.ProcessRequest method, the SharePoint application runtime is busy building an impersonation context of the calling user. This means that you CANNOT access SPContext.Current UNTIL the ProcessRequest method. This also means within the constructor of the handler OR from a factory pattern-- regardless of whether it's a Page or IHttpHandler endpoint. Note that this is a COMPLETE CHANGE OF BEHAVIOR (processing timeline) that the infrastructure update introduces. Bottom line-- this means that if you are implementing IHttpHandlerFactory instances, you cannot access the SPContext.Current object or anything deriving from there in the factory—you must wait until IHttpHandler.ProcessRequest. (NOTE: I haven't tested this, but this also will affect HTTP modules). The following code sample demonstrates the bug. The handler factory will fail every time, while the handler will work every time. using System.Web; namespace NGSupport{ // Supported code: works every time To test this out, compile this into a DLL called "NGSupport" and register the following handlers in web.config (may require elevated or WSS_Medium trust): <add verb="GET,HEAD" path="foo.test" type="NGSupport.TestHandlerFactory, NGSupport" validate="false" /> You should see that foo.test will work before the infrastructure update but break after it's applied, however you'll see that bar.test will always work as that is the supported code path. Props to the NewsGator dev, support and qa teams for identifying and resolving this issue quickly. July 13 Pre-order on Amazon: Developing Service-Oriented AJAX Applications on the Microsoft® PlatformWe're live on Amazon-- and to celebrate I'm giving away the first confirmed pre-order. The first person to send me proof of pre-order (you know how to reach me*...) will get a free signed book from me and a refund of your purchase price! (How can you lose????)
A big shout-out to my book team, without whom the book really would have been less interesting: my tech reviewer Per Blomqvist, my editor John Pierce, and my peer review team Mikhail Dikov, Darrin Bishop, Nick Swan, Al Pascual, Alvin Bruney, Mark Collins, Morgan Everett and Tim Colton. Of course, a bigger shout-out to my NewsGator dev team, Lane Mohler, Sherstin Lauman and Brian Agnes for working out and refining a kick-ass AJAX architecture with me over the last several years. This book reflects what we all learned at NewsGator! Oh, and a big thanks to Sallina for letting me write this book... I couldn't have done it without my wife's support. I'm just wrapping up chapter 8 now, with at least 3 chapters left to go. I'm also going to be releasing a MAJOR update to the SharePoint AJAX Toolkit based on this book (the last one was based on Inside WSS). If you're writing AJAX code based on the SharePoint AJAX Toolkit, I'd love to hear from you and compare notes. * @danlarson.com July 03 Book plug: Real World SharePoint 2007I just picked this book up to help me through forms based authentication and setup. My friend Stacy Draper wrote the chapter on forms based authentication, so it was a no-brainer to read Stacy's methods rather than futzing with it myself. It took me an hour to read through the chapter and set it up. There's some other great topics in there too, so check out the table of contents and add it as a special-case book to your library. It's chock full of good advice, tips and tricks from real world SharePoint experience as the title suggests. Check it out here: Real World SharePoint 2007 (Amazon). June 13 Elevated Privilege with SPSiteHere is a code sample of a utility class for elevated privileges using the best practices outlined in my last post. 99% of the time you'll be able to get the system token using site.SystemAccount.UserToken. However, you may need to elevate privilege if the current user doesn't have permission to read that object from the SPSite. In this case, you'll need to elevate privilege just to get the user token-- but we don't want to perform any operations inside RunWithElevatedPrivilege, we only want to get a token out (which is basically a simple byte array). You could also cache the system token in the application if you needed to, although I'm not sure I'd endorse that. The following static class includes two methods that will reliably run in all security contexts, assuming the assembly has the right CAS permissions. The GetSystemToken method returns a token, while the GetElevatedSite returns an elevated SPSite context. Be sure you wrap these in a using statement to avoid any leaks, and you're safe to pass in the SPContext.Current.Site object to these methods. Also, these methods should be used in working with SharePoint's security, not just to bypass it. Just because you can doesn't mean that you should, so be sure to practice trustworthy computing practices in your code. using System; namespace LitwareSecurity /// <summary>Gets a UserToken for the system account.</summary> // Only use runwithelevated to grab the system user token. June 09 Link: How we did Social Sites 2.0Today, we're shipping NewsGator Social Sites 2.0. Check out my guest post on the Microsoft SharePoint Blog: How We Did It: NewsGator Social Sites 2.0 - Enhanced Social Computing on the SharePoint Platform June 06 Best Practices for Elevated Privilege in SharePointElevated Privilege can be used to bypass or work with security, and can be performed either through SPSecurity or through impersonation techniques involving the SPUserToken and the SPSite class. It's one of the most misunderstood aspects of the SharePoint API, but in general you should always prefer impersonation using the SPSite class and SPUserToken objects. While I've been ranting about SPSecurity over the last few days, it can be useful for running code under the context of the application pool for code that access network or file resources, or for MOSS code that does not support impersonation through the SPSite object. Without further introduction, here's my list of best practices for elevated privilege code in SharePoint that will help you create more reliable applications for the enterprise.
June 05 SharePoint Security: The Evils of RunWithElevatedPrivilege (and our hero, SPUserToken)Since I've been ranting on this for a few days, I thought I'd wrap it up. When SPSecurity was first found, we thought it was the best thing in the API since since SPPeanutButter. We used it... we abused it... we loved it. Over the course of the last few months though, it betrayed us. We started to see all sorts of obscure bugs when working with the SharePoint object model within the delegate in RunWithElevatedPrivelege. One such issue was with My Sites. Somehow, we managed to abuse SPSecurity.RunWithElevatedPrivilege enough to disable MySite creation in the current ASP.NET application in completely unrelated code. Through simple calls sent through RunWithElevatedPrivilege we were able to corrupt the ASP.NET application instance so that MySites could not be created, with another misleading error message on the failed My Site creation page. QA loved this, of course. As the MSDN documentation says, SPSecurity.RunWithElevatedPrivelege "Executes the specified method with Full Control rights even if the user does not otherwise have Full Control." What it does is it uses the Win32 ImpersonateSelf API method to drop down to the thread's identity. There's a lot of hairy native code that's used to do this... just check out the method with Reflector. What we found was that all SP object model instances need to be created and disposed of inside of the delegate-- and even that can cause obscure bugs. I'm not recommending to never use SPSecurity-- but I will recommend to never use SPSecurity to access or manipulate the SharePoint object model. There's too much overhead, too much chances of introducing obscure bugs, and too much potential abuse. Only us SPSecurity.RunWithElevatedPrivelege to use the application pool's credentials for network calls. And for that, you may be better off simply using WindowsImpersonationContext and WindowsIdentity.Impersonate(IntPtr.Zero). For all other impersonation needs, use the SPUserToken to impersonate. Remember that the elevation of the object model happens through the SPSite constructor- no matter which elevation method you use, either through RunWithElevatedPrivilege or though simple impersonation using the user token. To impersonate the SYSTEM and use elevated privilege, get the user token from the SYSTEM ACCOUNT. Fortunately, the SystemAccount SPUser is a property of any SPSite object. So instead of using SPSecurity.RunWithElevatedPrivelege, you can use the following code to perform elevated actions: SPUserToken sysToken = SPContext.Current.Site.SystemAccount.UserToken; June 03 Please, just say no to RunWithElevatedPriveleges!You were warned. But you just HAD to use SPSecurity.RunWithElevatedPrivileges. See what you did??? June 02 RunWithElevatedPriveleges kills baby lolcats.It's official. SPSecurity.RunWithElevatedPrivileges is one of the most evil methods in the SharePoint API. Just say no, and use the SPUserTokens for impersonation. Please, it's for the lolcatz.
May 27 Troubleshooting SharePoint CAS (Code Access Security)Last week I spoke at the Rocky Mountain (Denver) SharePoint User Group and we talked about CAS. CAS is great because it limits what your code can do. For example-- you can know that my code won't compromise x because it doesn't have permission to even talk to type x. It can be difficult for developers that aren't familiar with CAS to grasp the concepts. Typically, your project CAS requirements can be determined early on in the project lifecycle, and don't change often over the course of development. For example-- the CAS policy for NewsGator Social Sites hasn't changed since version 1.0 over a year ago. We also NEVER ever manage CAS manually-- we add the security permissions to the WSP solution package, and let SharePoint manage CAS for us. But how do you determine what CAS settings you need? To start off with, always start off by running SharePoint in minimal trust. Also, enable debugging and the full call stack in web.config. The SafeMode node has a CallStack attribute that you'll want to set to true. With this, you'll get the full yellow screen of death rather than SharePoint's happy-happy joy-joy blue screen of "an error has occurred". With this set up-- when your code encounters a CAS error, you'll get a message similar to this: SecurityException: Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed. [Full call stack follows... great reading, but you'll have to find your own. Really, it's not that hard to find!] With this, we know that we need the CAS permission "System.Security.Permissions.SecurityPermission". Most permissions are conveniently located in this namespace, BTW. With this information, we can easily create the following IPermission entry in the manifest.<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" /> However, there are still more attributes you'll need to get the full/required trust that the permission can define. I don't think I have a GREAT answer for this, but I use Reflector to get that info. Also, you can do a simple search and find the syntax-- either in MSDN, exising CAS settings in the permission files in the 12 hive, particularly \12\config\wss_minimaltrust.config, or with the google. The best way to do it is to reference the type that threw the exception to see what it's CAS requirements are. For example, I was trying to use the System.Diagnostics.Process class in some recent debug code. The error message I got from the stack trace wasn't too complete, it just showed that the security demand failed. So I looked at Process with Reflector, and that shows the CAS that you need to work with Process. [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust"), PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")] public class Process : Component {/* class here... */} It turns out that Process requires full trust to run... so it isn't going to run at all with partially trusted code! Back to my earlier example-- the full permission that I needed in my test case follows: <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" One thing I like to do is keep a reference of common CAS settings handy. Because although I LOVE typing in XML, there's more interesting XML to hack than CAS. So keep a CAS reference handy-- here's a relatively complete sample CAS entry for one of my commercial projects. Note that it's for an unrestricted WebPermission to make network calls-- you could further lock that down to a specific URL-- and it's also for the required permission set for using SPSecurity.RunWithElevatedPrivileges. <PolicyItem> </PermissionSet> Related reading: If you don't know what the WSP solution package deployment is-- that is a prerequisite to CAS management. Take a look at the online docs or at codeplex projects such as STSDEV or WSPBUILDER for better ways to build solution packages, or use my old-school VS project template from codeplex.com/sharepointsdk. SHAMELESS PLUG: Want to know more about CAS? Chapter 10 of Inside Microsoft Windows SharePoint Services 3.0 has a great reference on CAS, and more great documentation on the WSS security model. May 26 NewsGator invades ScrantonCheck it out here: http://launchpad.enterprise2conf.com/node/36. It's a great demo of SocialSites embedded in a cheesy The Office spoof. (Yeah, that's my code they're using!) May 20 SharePoint Elevated Privilege without RunWithElevatedPrivelegeRunWithElevatedPrivilege drops the identity of the code to the process user, which is either the current user in a console application or the application pool if run in the web application. It requires a ton of CAS permissions and is generally overkill for what you need to execute as system. And did I mention-- the Microsoft support policy on it is a little fuzzy? It can also lead to bugs as objects cannot reliably be passed into the delegate-- especially constructs like the SPUser object. (There are some VERY obscure bugs that can occur when passing references across those boundaries!) A better way to do perform system actions is to impersonate the SHAREPOINT\system account. Impersonation is a concept that is built into the object model, but is underutilized by developers. The SPSite object takes an SPUserToken object in its constructor in order to support impersonation. (This does require Impersonate="True" for the Microsoft.SharePoint.Security.SharePointPermission permission class). You can impersonate any user when creating the SPSite context-- so to get the system account, just use the magic system account "SHAREPOINT\system". Here's a code sample of SYSTEM ACCOUNT impersonation. The SYSTEM ACCOUNT uses the login name "SHAREPOINT\system" internally while it will use the process identity (usually that means the application pool identity, but it could be the service identity if a task was run as a timer job) when making external network calls. Note that the account is abstracted, and when a request comes into the system AS this account it will take on the identity of SYSTEM ACCOUNT. Here's the code sample. Grab a user object, and then grab the SPUserToken for impersonation: var superman = SPContext.Current.Web.AllUsers[@"SHAREPOINT\SYSTEM"]; using (var site = new SPSite(SPContext.Current.Web.Url, superToken)){ using(var elevatedWeb = site.OpenWeb()){ Because the thread identity hasn't changed, this will produce more stable code in most circumstances, although you should be aware that ONLY objects that are referenced from the elevated site context will run as system. //Updated on 5/22/08 -> the correct method to get the system user is with the AllUsers property of the SPWeb object, since EnsureUser requires management permissions anyway... Hardware Report: HP Tx2000 series Tablet PCI upgraded my laptop this week to the HP tx2000—and it runs Server 08 x64 flawlessly. Everything works flawlessly on 64bit Server, including the webcam, wireless, tablet functionality, and Bluetooth. If you’re looking for a small laptop (12”) that’s speedy and runs server I’d recommend this one, and it’s only around $1200 pimped out from HP with the 2.4ghz Turion (I also added 4gb ram and a 72000rpm drive from my last notebook). For writing code-- NOTHING beats un-virtualized development. But VMs for testing and staging are darn handy, and the virtualization support in the Turion chip is excellent. My theory: virtualization is a crutch for environments that can't be scripted! Buy my old Laptop (HP tx1120us) with Server 2008 ($800)I'm selling my old laptop-- I'll even include Server 2008 pre-installed with all the drivers if you supply the MSDN license. It's an HP tx1120us tablet PC with 2gb RAM (you can upgrade the RAM to 4gb for $75 @ TigerDirect.) It runs a 64bit dual core AMD Turion (with hardware virtualization support) and comes with Vista Home Premium. Comes with a built in webcam, wireless G, gigabit ethernet, stylus, fingerprint reader, remote control for Media Center, and a 12" swivel touch screen display. If you're interested email me at buymylaptop@danlarson.com. It's under warranty until June 3 and you can extend that. It runs Server 08 BEAUTIFULLY. May 08 The Revenge of Captain AJAXI've got an official page for the book-- and we've got a formalized title as well, "Developing Service-Oriented AJAX Applications on the Microsoft® Platform" While there's not much there yet (no Amazon links yet... ), check it out: http://www.microsoft.com/MSPress/books/12793.aspx Here's how the book is described (and it's pretty accurate!) Your essential guide to building Rich Interactive Applications (RIAs) using Microsoft technologies Delve into the fundamental architectural principles and techniques for developing service-oriented AJAX applications for the enterprise. This guide offers a code-heavy, example-based approach to learning how to write a modern services API and an AJAX front end that can easily be extended, reused, and integrated by third parties. Focusing on Microsoft technologies and enterprise servers, including Microsoft SharePoint® Server 2007, ASP.NET AJAX, and Microsoft .NET Frameworks 2.0, 3.0, and 3.5, this book walks you through a client-centric UI architecture programmed against an XML service-oriented backend. Topics include the Microsoft AJAX Library, Web services and an XML API, client-side XSLT, JavaScript AJAX communication, and integration with Microsoft servers. The book does not attempt to be an exhaustive reference, but focuses instead on fundamental architectural principles and guidance. Also, the expected street date is 11/12/2008, but it might ship sooner:) April 28 Book Plug: MOSS Enterprise SearchA few weeks ago I was given a copy of "Inside the Index and Search Engines: Microsoft Office SharePoint Server 2007" (thanks, Ben!). I've seen this book and passed on it before because of it's title... I don't really care about how Microsoft implemented their index engine, I'm just not that type of guy. However, this book was so much more than that-- it's a very practical book on integrating custom search into MOSS. It's a much needed resource, there isn't this kind of in-depth programmatic reference available outside of this book. Whether you want to customize the search results with your own metadata or just styles, or if you want to use search programmatically throughout your applications, or if you want to configure MOSS search against your own application data through direct SQL access or through web services-- this book is for you. It's also heavy on the code-- it's a book geared to developers, not administrators. It's also a very focused book-- all you're going to read about is search. But if you need to customize or integrate with MOSS enterprise search, especially if you work at an ISV (and especially if your PM is named "Ashley"), this book is for you. You can pick up a copy here or wherever fresh produce is sold: April 26 Windows Live (Messenger, Writer, etc.) on Windows Server 2008After several months of not using IM (oh it was SO freeing!) I finally decided to find a version of live messenger that works on server. I do like Live Messenger because it works well with the webcam for video calls. I finally found an old version that installs quite nicely-- and then learned that you can easily upgrade to the latest release and by copying the installed version from a Vista box. Forget about installing the new versions directly-- but you can install version 8.1, and then copy the current 8.5 binaries you installed on your Vista box. Here's the steps: 1. Install Windows Live apps (messenger, writer, whatever) on Vista. 2. Get Windows Live messenger v 8.1 here, compatible with Server 08 x64 (from downloads.microsoft.com). 3. After installing messenger 8.1 on Server, exit Messenger, copy over the files from C:\Program Files (x86)\Windows Live from a Vista box, and run on Server the exe at C:\Program Files (x86)\Windows Live\Messenger\msnmsgr.exe. You can also run Live Writer (doesn't need an install as it's a .NET app-- run the exe from the directory). A final word of caution: NEVER download Microsoft files from third part sites to try to workaround, as you're opening yourself up for viruses. But this hack gets you up and running using official Microsoft software. Who knows, you might even get product updates. April 18 MVP Summit ReportThis week I attended the Microsoft MVP Summit in Seattle. Here's why we love Microsoft: Microsoft listens, and is also transparent with it's key influencers and contributors. This week I heard product plans for Microsoft Office SharePoint Server as well as the ASP.NET AJAX framework in both open forums and closed-door meetings, and was given the opportunity along with the rest of the MVP teams to help shape the platform for the next product release cycles. Oh yeah, and one heck of a party: SharePoint developers (and admins too) have a great community bond that really shows in gatherings and throughout the year as well. Lawrence posted some great photos and a recap of the SharePoint MVP summit here. There's nothing I can say about what is coming in SharePoint vNext other than there's been a lot of MVP feedback. Regarding ASP.NET AJAX, MUCH of the AJAX stuff is already public (details here), but there are a few surprises up their sleeves. Of course, the AJAX Control Toolkit is very important to the AJAX client stack and will continue to get love from Microsoft, which is a great model that other product teams would do well to emulate, where the project is an effort of both Microsoft and the community, which also enables both out-of-band releases and community contributions-- something we really need for those products with 3 year plus release cycles. April 08 Ajax Memory Leaks ExplainedDouglas Crawford has a great site about JavaScript (the world's most misunderstood, yet most popular, programming language) where he explains memory leaks. If you create HTML through script (as is typical with AJAX applications)-- your application *has* memory leaks in IE if you have click events in the HTML and you don't remove them. Check out his article on memory leaks which include sample demo pages. The leak is only a factor for IE users-- and yes, it's an issue in IE7/8. To clean up the memory leak bug, you MUST purge the DOM elements of functions before removing them from the DOM. Here's a code sample, gratuitously ////From crockford.com: If you're an AJAX developer, I highly recommend reading through his site. Especially his notes on object orientation, inheritance and the JavaScript language. April 07 Immortalized in the SharePoint SDKIn February's WSS 3.0 SDK release, I found myself immortalized in the included Technical Articles CHM file. (Look for topic "Book Excerpts: Inside Microsoft Windows SharePoint Services 3.0") Props to my partner in crime Ted Pattison! Get the SDK here. April 04 Best Laptop Mouse EverIf you use a mouse with your laptop, you need this mouse. You just can't beat it's feel, and the USB wireless receiver is so small you'll never remove it. Logitech VX Nano UPDATE: April 01 Real error messages in SharePointOk, so SharePoint DOES show the "An error has occurred" page on purpose-- it's there to provide "maximum security" for the portal by not showing detailed error messages to the user for unhandled ex | ||||||||||||