![]() |
|
Spaces home Daniel Larson's Develope...ProfileFriendsFiles | ![]() |
|
August 11 Client Side AJAX History Support with Sys.ApplicationOne of the cool new features of the 3.5 SP1 Microsoft AJAX Library is a history framework, which adds support for backwards and forwards navigation using history points. History points can be added any time, and contain a JavaScript dictionary that helps you serialize and deserialize the state of the application or control. To enable history, the ScriptManager must be set to support history: <asp:ScriptManager ID="ScriptManager1" runat="server" EnableHistory="true" /> To add a history point, simply add a JavaScript dictionary object and a title for the history point: var state = { message: "Hello World!" }; To handle the navigate event which is fired by Sys.Application upon client back button usage, create a handler: function onHistoryNavigate(sender, eventArgs) { Finally, you'll need to add the handler to Sys.Application. Note that because navigate is an event, multiple consumers can add a handler to the event: Sys.Application.add_navigate(onHistoryNavigate); In a control, you'd want to call remove_navigate to clear your event handler. Finally, the following sample page demonstrates the use of history through the creation of 3 history points. As each history point is added, the navigate event is raised (synchronously) causing the final state of the page to have the 3rd history point loaded. The user can then navigate back and forth between the 3 languages of Hello World. <%@ Page Language="C#" %> Also note that this is new functionality in the 3.5 SP1 release-- the server control syntax will cause a compilation error in earlier frameworks. Finally, a shameless plug: I've got more details on history management as well as the rest of the AJAX library in my new book, available later this year: Developing Service-Oriented AJAX Applications (Microsoft Press 2008). August 08 .NET 3.5 Service Pack 1The .NET 3.5 Service Pack 1 RTM release is now available through the SQL Server 2008 install media, available on MSDN. Be sure to uninstall any previous 3.5 SP1 betas before installing it. I've already implemented the new JavaScript history manager support into our product, which I'll blog about shortly. August 01 The Cuil Search EngineJuly 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:) |
|
|