Microsoft

Blog Categories

Subscribe to RSS feed

Archives

Follow our Microsoft Technologies board on Pinterest

Brian Hulse

Posts by this author: RSS

MigrateUsers Method Breaks All Web Application Permissions

On my current project we are doing a migration from SharePoint 2007 to SharePoint 2010. Updating our current authentication scheme (a mix of .Net forms and Windows authentication) to utilize claims authentication is one of the requirements for this project. One major difference between how SharePoint treats users in SharePoint 2007 and SharePoint 2010 claims authentication mode is the username it reads to resolve users. In SharePoint 2007 these were pretty plain representations of a username you would recognize. This changed to a more complex string in SharePoint 2010 to allow for resolution of users from a larger number of possible sources. The below table gives an example of this; please note that there are other authentication types I am leaving out.

Authentication Type SharePoint 2007 convention SharePoint 2010 convention
Individual Windows User (NTLM) domainusername i:0#.w|domainusername
Active Directory Group (NTLM) domaingroupname c:0+.w|s-1-1-11-111111111-1111111111-111111111-1111 (SID for group)
Forms Authentication formsprovidername:username i:0#.f|formsprovidername|username
Claims Authentication (custom provider)   i:0e.t|providername|username

Microsoft added a method on the SPWebApplication object that you can call to migrate your users, you can call it in powershell like so:

$w = Get-SPWebApplication “http://yoursharepointsite.com/”
$w.MigrateUsers($True)

This command will change all usernames from the 2007 convention to the 2010 convention.

It seems a little too easy and too good to be true. Upon running this method the first time the conversation between me and the support engineer I was working with went a little bit like so (language in real life may have been a tad more colorful):

Me: Did you run it? I still get access denied on the web application.

Support: Yes, it finished with no errors too. Oh crap, I get access denied too! I’m giving your account full access to the web application with a user policy in CA, try it again.

Me: I’m still getting a darn access denied message. No frickin’ way, did we just kill SharePoint?

Support: SharePoint declared deceased at 3pm on 8/5/2011. Shucks.

After we stopped freaking out, we tried re-attaching a copy of the content database taken before running the MigrateUsers method. This didn’t help, we still got access denied everywhere on the web application even with a Farm Administrator account. We ended up having to recreate the web application and re-attaching the earlier copy of the content database to get it back up and running. After trying this multiple times and having it fail every time I did some searching on the web. I found a few mentions of updating the PortalSuperUser and PortalSuperReader account for the web application so they were in the correct user format before the user migration. After trying this a couple times and getting the same result as before we found the problem!

We were creating our web application with a powershell script. When we set the PortalSuperUser and PortalSuperReader accounts in the script we were using the old format (domainuser) and it seemed to be persisting somewhere in the content database causing the user migration to break all permissions on the web application. To fix this we updated our powershell script to create the web application with the super user and super reader accounts using the new format (i:0#.w|domainusername) and this fixed the broken permissions after running the MigrateUsers method.

If you need to customize your usernames further (i.e. your user’s domain is changing or you are moving from forms to claims authentication) you can modify the username string directly. If your SharePoint 2010 application has the latest patches applied Microsoft made a callback available in one of the cumulative updates so you can hook into the MigrateUsers method and run your custom code. If you are still on the RTM version you can modify the user profile properties directly through powershell.

Claims SSO in an Anonymous Access SharePoint Environment

Note: The below method is good for both single sign on and persistent login scenarios in a SharePoint environment with anonymous access enabled.

I recently had to wrestle with implementing single sign on (SSO) between two SharePoint web applications that have anonymous access enabled. If you have read Programming Windows Identity Foundation (I recommend you do if you are planning on implementing claims authentication) you would know that to implement SSO between two secure SharePoint web applications with the same identity provider is not too difficult. If the user is authenticated to one application you can count on the default redirect of non-authenticated users from the second application to your identity provider. The provider will recognize that the user is already authenticated to it (after you program it to) and redirect you back to SharePoint to create the FedAuth cookie you need to access the second application.

Things start to get a little tricky when you throw anonymous access into the mix. The main difference being, you cannot rely on SharePoint to recognize that a new user needs to be authenticated to the STS. This was triggered by an anonymous user trying to access a secure site before, now that your application is anonymous SharePoint does not have this trigger to utilize. That means we are going to have to write some code to create our own trigger.

The solution consists of two parts, a user control on the SharePoint application, and an application page on your custom identity provider (sometimes called an STS or Secure Token Service). The control is going to make a JSON call to the page that lives on the provider. The page on the provider just returns whether or not the current user is authenticated. If the user is authenticated, the control will redirect the user to the provider to be authenticated to the new application.

Let’s take a look at the Render method of the control that will live on our SharePoint application. NOTE: this code is using the jQuery library to make the JSON call.

1: protected override void Render(System.Web.UI.HtmlTextWriter writer) 2: { 3: if (Page.Session.IsNewSession && !HttpContext.Current.User.Identity.IsAuthenticated) 4: { 5: SignInRequestMessage message = TrustedIdentityHelper.CreateTrustedSignInRequestMessage(); 6: 7: string STSUrl = TrustedIdentityHelper.STSUrl(); 8: 9: HttpContext.Current.Response.Write(String.Format(

"<script type="text/javascript">

10: $.getJSON(“{0}{1}”, null, 11: function (data) { 12: { if(data.IsAuthenticated.toLowerCase() == “true”) 13: {{window.location.replace(“{2}”); }} 14: }}) </script>”, 15: STSUrl, 16: “AuthCheck.aspx?Callback=?”, 17: message.RequestUrl)); 18: } 19: 20: base.Render(writer); 21: }

.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode, .ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode pre
{font-size:small;color:black;font-family:consolas, “Courier New”, courier, monospace;background-color:#ffffff;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode pre
{margin:0em;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .rem
{color:#008000;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .str
{color:#006080;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .op
{color:#0000c0;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .html
{color:#800000;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .attr
{color:#ff0000;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .lnum
{color:#606060;}

You can see that I have a class which assists with creating sign in request messages as well as gives me the URL to my custom provider; I will use both of these if the current user needs to be authenticated. This control outputs javascript on the page that makes a JSON call to AuthCheck.aspx which is located on the identity provider site. If the call returns true (i.e. the user is authenticated to the identity provider) then I redirect the user to the provider to be authenticated. The reason that I only fire this control when it is a new session is because if I took that check out this control would make a JSON call to the STS for every anonymous request. If you have a high traffic site, having a lot of people making frequent JSON calls to your identity provider could cause performance problems.

The AuthCheck.aspx page that receives the JSON call from this control and returns the result is very simple, it is a basic page with a few lines of code in the Page_Load method.

Here is the code for that:

1: protected void Page_Load(object sender, EventArgs e) 2: { 3: Response.ContentType = “text/javascript”; 4: string callback = Request["Callback"]; 5: 6: Response.Write(String.Format(“{0} ({{“IsAuthenticated” : “{1}”}})”, callback, User.Identity.IsAuthenticated.ToString())); 7: }

.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode, .ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode pre
{font-size:small;color:black;font-family:consolas, “Courier New”, courier, monospace;background-color:#ffffff;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode pre
{margin:0em;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .rem
{color:#008000;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .str
{color:#006080;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .op
{color:#0000c0;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .html
{color:#800000;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .attr
{color:#ff0000;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassDD2020F98DAE47F59C5986460CDE3F61 .csharpcode .lnum
{color:#606060;}

That is the gist!

Problem deploying content types that inherit during SharePoint 2010 upgrade

I am currently on a project to upgrade a custom SharePoint 2007 public facing internet site to SharePoint 2010. While testing out our custom site templates by provisioning sites we ran into some issues with custom content types supposedly not existing during the provisioning. This was very perplexing as these content type definitions deployed fine in SharePoint 2007. Doing a lot of testing we tracked the issue down to the content type ID. All of the content types that would not deploy inherited from the built in ‘Page’ content type so they all started with ‘0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39’ then, following the content type ID guidelines, we added ‘00’ and then a new GUID for our custom page base and anything inheriting from this base had ‘01’, ‘02’, etc. on the end of the ID. When we activated the feature that contained these content types on a different site collection there was no error however we could not see the content types either in the UI or by listing them with PowerShell, but it did exist in the content database. This was a very perplexing situation as nothing was telling us why these content types wouldn’t show up, the site columns were deploying fine, the ID was created according to guidelines, the ID was being deployed to the content database, it worked in 2007, and we weren’t seeing any telling errors when deploying this feature on other sites.

So, after nearly giving the team a heart attack by telling them, “We may not be able to do a database attach at all,” (this would mean 1+ months solid of loading data to our site to get it back to where our 2007 environment is) and spending nearly a day and a half googleing/binging and trying to figure out why our IDs were broken, I FOUND THE SOLUTION. This is basically a reminder to everyone doing an upgrade to SharePoint 2010: Always look at where things have changed between versions (especially for things that are xml definitions and not compiled code). Yes that’s right there is a new property on the ContentType element in SharePoint 2010. If you look at the MSDN article on the ContentType element you will notice the ‘Inherits’ property which was not in SharePoint 2007. If your content types are inheriting from out of the box SharePoint content types you MUST include ‘Inherits=”TRUE”’ in your ContentType element.

I will definitely be looking for these types of ‘gotchas’ much sooner in the future. Hopefully the day and a half I spent banging my head against the wall will help some of you going through this same process.

SharePoint Connections Conference 2010 Overview

I got the opportunity to attend the SharePoint Connections Conference this year at the Mandalay Bay in Las Vegas. This trip was very exciting for me, being both the first conference for me, as well as my first trip to Las Vegas. It was a great experience and I hope I have another opportunity like this in the future. There were many interesting sessions put on by a lot of SharePoint rock stars which I’ll give an overview of in this post.

This conference, known overall as the Microsoft Connections Conference, also had sessions targeted at ASP.NET, Visual Studio 2010, Windows, and SQL Server. Knowing this I decided to attend the ASP.NET keynote speech put on by Scott Guthrie. It was a very interesting talk covering some new tools for developing .NET applications in Visual Studio 2010. Scott focused on NuGet for a while, which is an open source package management system for .NET. It can really streamline using third party libraries during development. They displayed this functionality by seamlessly finding a 3rd party library, installing it, and using it’s build in templates with the sample MVC application. Another interesting functionality demonstrated was a new view-engine included in ASP.NET MVC 3 called “Razor”. Scott has a great introductory blog post for understanding Razor and how to implement it.

Paul Stubbs gave an interesting talk about the SharePoint 2007 to SharePoint 2010 upgrade process. He mainly focused on what you should be documenting before you upgrade as well as tips on how to pick the right upgrade strategy. Of the three types of upgrades: in-place, database attach, and a mix of the two; most speakers agreed that they are seeing over 90% of people doing a mix of in-place and database attach upgrades. This talk was similar, if not a little more high-level, to the SharePoint 2010 upgrade drilldown talk given later in the week by Joel Oleson. Joel’s talk covered some of the same topics as the one Paul gave, but he also drilled down into more details to help decide which type of upgrade you need to consider as well as figuring out what of your custom code will need to be upgraded. Of the custom code that needs to be upgraded, the most daunting seems to be custom site definitions and custom features. If you have a highly customized SharePoint site this can take up a lot of testing and development time in your upgrade process. Joel also highly stressed the importance of running the stsadm operation “preupgradecheck” in addition to the powershell commandlet “Test-SPContentDatabase” before undertaking any type of upgrade. Check out his blog post on this topic for more detailed information.

Gary LaPointe gave one of my favorite talks of the week titled, “Leveraging the SharePoint 2010 User Experience Enhancements.” Sadly I only caught the second-half, but it was still very informative. Gary covered how to use the built in notification, status message and dialog functions to quickly create and display messages to users in your custom solution. This could end up being very useful and time-efficient in the field as it will save time spent styling and coding custom notifications. It will also help keep the user familiar to the notification UI you are presenting to them.

My favorite talk of the week was titled “Extending the Visual Studio 2010 SharePoint Tools” given by Ted Pattison. If you’ve played around with developing and deploying SharePoint 2010 solutions in Visual Studio 2010, you know there are a lot of enhancements that make developing for SharePoint much easier than in the past. Ted showed us ways to add items with custom actions to the context menu, write to the output dialog box, as well as adding custom deployment steps that Visual Studio will execute for you. I think there is a lot of potential here to create custom tools for certain projects on the front-end, allowing for more stream-lined development through either making custom templates available to developers through the context menu as well as creating project/environment specific deployment actions that interact with the SharePoint environment you have connected to your project.

Overall it was a great first time in Vegas that I won’t soon forget. I didn’t have time to write about all of the sessions I attended, but rest assured they were all very informative and I feel like I learned a lot at the conference. A big thanks to all of the presenters who put together great sessions (I didn’t even sleep through one!). You should see some blogs coming through demonstrating, in more detail, some of the things I learned or that piqued my interest at the conference.

Updating Content Types In SharePoint 2010

When it comes to content types the best practice is to define them up front and do not change them, but in real life this is not always practical. In my experience, when working with content types, at some point the client is going to want to change something whether it is a column or property on the content type. The problem comes when you want to deploy an updated version of this content type to many lists using it across the site. When deployed, if the updated content type definition was part of an existing list, the definition on that list would not update. One of the only ways to remedy this was to go into the UI and update the columns that way. This can potentially be very time consuming if you have a lot of site collections using the same list with the updated content type definition.

That was the issue with SharePoint 2007, let’s see how 2010 works.

To start I created a content type that inherits from “Document” with two dummy columns as you can see below. The idea that a content type definition at the site level and one at the list level can be different is an important distinction. As you can see in the image below the content type on the list inherits from the same content type at the site level.

contentTypeDef_initial

First I want to try to add a new optional text field to this content type. This would seem like our best bet, because there would be no conflict with trying to remove existing fields that may have data in them. I was able to add an extra column to the content type, but the process wasn’t as straightforward as just updating the wsp (as I was hoping), it is more or less the same as updating the columns manually in 2007. I had to upgrade my solution, reactivate my feature, then navigate to my content type in the UI (it can be found easily through the list settings page) and add the column manually. I then got an error telling me the column already existed:

image

After selecting “Go back to site” this new column is part of any of the items using this content type:

image

It is interesting to note that I was able to add a Required field using this method as well. The field is not actually required until you try to save the item after the field is added.

To remove an existing column you have to use the UI as well. This time I will remove a column that an item of this content type has an existing value. If you go into the content type definition in the UI and select one of the columns you will see a button that will allow you to remove it along with some other properties:

image

If you keep the “Update List and Site Content Types” option as yes the column will be simply deleted from any inheriting content types (WARNING: you will lose this data). If you leave the option at “No” content types at the list level will not be changed.

So this process wasn’t updated in 2010 to allow updating content types that are in use via WSP. I believe this is as designed to limit the impact of a content type change on existing objects, but I was hoping that there might be a new property available on the content type definition that would allow this type of upgrade, but after spending time looking I don’t think it exists. It looks like I am going to have to stick to using a custom console application to update all of my content types.

Information Management Policy Conflicts – SP 2010

Information management (IM) policies can be set in a number of places in SharePoint 2010. The question is: When you have conflicting policies, which policy wins out?

To test this I created conflicting IM policies in a few different places that could affect one document. I decided to use the Labels policy which allows you to add a label to any document when it is printed. First, I created a policy for the ‘Document’ content type in a document library I created. Next, I created a content type that inherits from the Document content type with another IM policy. I’m interested to see if the IM policy I set on the ‘Document’ content type will be picked up by the new inheriting content type so I also created a document content type which inherits from ‘Document’, but does not have an IM policy.

You can create IM policies by accessing the ‘Information management policy settings’ in the settings for that content type (the same goes for document libraries). Here’s a quick look at the options you have when adding labels:

image

After creating new documents and testing out it seems that policies do not affect inheriting content types, so policies were not conflicting in this case.

After testing out different scenarios with the original policies I created trying to force a confliction, it just didn’t seem to be working. To force a confliction I decided to set a policy on the ‘Document’ content type at the site collection level that conflicts with the one that I created on a document library. This was the result:

image

At first glance it looks as if the policy I set at the site collection level is overriding the policy i set for the specific document library, but after going back to verify the document library’s IM policy I ran into this:

image

It seems that conflicting policies at different levels are not allowed, SharePoint will always default to the ‘parent policy’. As you can see I can’t even create separate non-conflicting policies for a single content type such as an expiration policy and a labels policy it always defaults to the parent.

Using the XSLT List View Web Part to style your data – SP 2010

SharePoint 2010 has finally done away with displaying list data using CAML with the XSLT list view web part. Now you can take advantage of the flexibility that XSLT can offer you. This is not to say that you can’t use your previous CAML statements in SP 2010, they are still supported, but hopefully after you see what is possible with the new XSLT list view web part you will leave CAML behind.

There are two main ways that you can change the view of your data. Use conditional formatting just like you do in Excel, or editing the XSLT directly. It is true that you could use XSLT with the Content Query Web Part in SP 2007, but in SP 2010 it is a lot more user-friendly. To show you some examples of the new functionality I created a list with professional athletes and the sports they play that we can play around with.

First you’ll want to add the XSLT list view web part to a page. I created a new page in SP Designer 2010 and then in the Insert tab selected the Data View option. From there just select the type of data you want to display, I’ll be using data from the ‘Players’ list.

clip_image002

Conditional formatting, basically, works the same as in Excel. You select a value, add a condition for that value to meet, and then apply a rule to that item. Here I will set all rows where the Sport = Baseball to have a red background.

clip_image004 clip_image006

It is also very straightforward to group and sort items, which I am a very big fan of. Clicking the Sort & Group button on the ribbon gives you options to sort and group items in different ways. I am going to group the list items by sport and have all groups expanded by default. It is interesting to note that in both the conditional formatting and sorting and grouping, all fields (and even some properties for these fields) can be used for calculations or groupings, even the default fields like ‘FileDirRef’.

clip_image008

And the result:

clip_image010

The built in functions to help you display data in different ways is very helpful, but the real customization comes into play when you play with the XSLT directly. In SP Designer you can switch to either the ‘Split’ or ‘Code’ mode which will show you the XSLT currently on the page so you can edit or create your own XSLT template to use. I created a template with simple ‘if’ statements to display a corresponding picture depending on the value for the Sport column. Here are the statements I added:

<xsl:if test="normalize-space($thisNode/@Sport) = 'Baseball'">
<img alt="" src="/Images1/baseball.jpg"></img>
</xsl:if>
<xsl:if test="normalize-space($thisNode/@Sport) = 'Basketball'">
<img alt="" src="/Images1/basketball.jpg"></img>
</xsl:if>
<xsl:if test="normalize-space($thisNode/@Sport) = 'Football'">
<img alt="" src="/Images1/football.jpg"></img>
</xsl:if>
<xsl:if test="normalize-space($thisNode/@Sport) = 'Golf'">
<img alt="" src="/Images1/golf-ball.jpg"></img>
</xsl:if>
<xsl:if test="normalize-space($thisNode/@Sport) = 'Soccer'">
<img alt="" src="/Images1/soccerBall.jpg"></img>
</xsl:if>

.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode, .ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode pre
{font-size:small;color:black;font-family:consolas, “courier new”, courier, monospace;background-color:#ffffff;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode pre
{margin:0em;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .rem
{color:#008000;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .str
{color:#006080;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .op
{color:#0000c0;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .preproc
{color:#cc6633;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .html
{color:#800000;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .attr
{color:#ff0000;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass827869EC849748BA97C0C651FF0B96D9 .externalclass0a016e8b1cbf4f49bf33d5539400146c .csharpcode .lnum
{color:#606060;}

And here is the result:

clip_image014

The SharePoint team has definitely put a lot of work into giving users many more options to display simple data out of the box. With a little more work you can display the data any way you like, and unlike with SP 2007 and the Content Query Web Part, SP Designer 2010 gives you instant feedback on how your custom XSLT is going to look on the page. Hopefully the new features offered with the XSLT List View Web Part will make displaying data across your SP 2010 site much easier.