Monday 8 October 2012

Convert existing SharePoint Web Application from Classic mode to Claims mode authentication results in all users getting "Access Denied" error or only view rights of the site

Scenario -
I had an existing SharePoint site that I had created with Classic mode authentication (not a good idea!) and due to certain requirements which needed to be implemented in this site I had to convert the site to Claims based authentication. Though I do not "claim" to be an expert in configuring "Claims" authentication I was aware of the simple process of converting Classic mode authentication to Claims mode.

As is true in most cases, I had commitments to meet and converting the site to Claims mode seemed an easy bit and was at the bottom of my priorities. However, after setting up most pieces of my site (which had anonymous access enabled, by the way) when I converted my site to claims mode I was surprised to see that I could no longer access my site with full privileges except with "System Account". Luckily, since I had anonymous access I was able to atleast browse the site with my other admin users and what I saw is that the user names appeared as "i:0#.w|domain\username". With the System Account I checked for the permissions of the site and the permissions were as earlier, nothing had changed. But, still no access.

Solution -
Please take a backup of your web application before running any of these scripts (it is a good idea to take a backup before running any major Powershell script) as it atleast helped me save face.

First of all below is the powershell script to convert classic mode site to claims mode

$webapp = Get-SPWebApplication -Identity "http://serverURL"
$webapp.UseClaimsAuthentication = $true
$webapp.Update()

As mentioned above after running this script access for my users was altered (removed, rather). Here is what you need to do in addition. But make sure you have your backup ready. The script is as follows -

$webapp = Get-SPWebApplication -Identity "http://serverURL"
$webapp.MigrateUsers($true)

Thats it! Seems pretty simple but it took me around 10 hours of searching before I reached this solution (makes me feel pretty dumb if you reached here in 5 minutes).

Caution! Caution! Caution! -
OK! There was a reason I asked you to have a backup before running scripts. This is what happens when you run the above mentioned scripts:

On executing the first script (to enable claims authentication) the SharePoint Content Database is made ready for claims based authentication but the already existing site users, who in my case were windows users, are not "migrated" to be understood by claims authentication. But SharePoint assumes all users to be claim users and renders them so. Therefore, a normal windows user - "Domain\UserName" appears as "i:0#.w|Domain\UserName". Furthermore, it uses the username in this same format to check for its permissions but does not find a matching entry for the user as the database has windows users - "Domain\UserName". So, the site will give you an access denied or, in my case, anonymous access privileges.

Note that the System Account will work since it's "Domain\UserName" is never used and System Account is a keyword used by SharePoint for your application pool identity. Therefore, it remains unaffected.

To overcome this situation we use the second script to "migrate" the users. MigrateUser($true) will convert all user accounts to claims format. After running this script user accounts are converted in the database to claims format, therefore, user names are read correctly by SharePoint, therefore, permissions for users are associated correclty by SharePoint and therefore, the site permissions work correctly.

Something very important to note here is that ideally, MigrateUser($false) should convert the user names back from claims format to the normal format, but it does not do so. This script will throw an exception and no change will be made to the database - so once you are in claim mode you cannot go back. Please refer this post to revert from claim mode to normal mode. Also note that these scripts are running on Web Applications so they will affect all site collections in that web application

Lessons learnt - I feel, that if you are creating a new web application in SharePoint 2010 always use Claims Mode Authentication as it gives you flexibility and you can avoid wasting your time on "migrating" users back and forth. Probably that is the reason why SharePoint 2013 has done away with Classic mode authentication and has only Claims-based Authentication.

5 comments:

  1. OMG YOU ARE AWESOME!

    Seriously. I though I was going to have to spend all night fixing this. NONE of the sites I viewed showed that it was as simple as having to migrate the accounts too. Not even the Technet article mentions this!

    I'd buy you a beer if I could! THANK YOU!

    ReplyDelete
    Replies
    1. You are welcome Matthew and thanks for your comment!

      Delete
  2. Great article. Thank you. I have spent the last 3 days taking our massive SP 2007 DB to SP 2013 (test run) and this was a very important piece of the puzzle.

    ReplyDelete
  3. Don't you need to setup AD FS and AD FS Proxy for Claims Authentication to work?

    ReplyDelete
  4. Dont you need to update it using $webapp.Update() after running the script for user id migration.

    $webapp = Get-SPWebApplication -Identity "http://serverURL"
    $webapp.MigrateUsers($true)

    ReplyDelete