Wednesday 4 June 2014

SharePoint User Migration– AD to ADFS


SharePoint User Migration– AD to ADFS

Excelent post by Pranab

Reference

http://blogs.msdn.com/b/pranab/archive/2012/06/27/sharepoint-user-migration-ad-to-adfs.aspx

 

1 Introduction

We have a good number of guidance articles and documents on SharePoint 2007 to SharePoint 2010 migration and also on classic to claim migration for SharePoint 2010 in both Technet and MSDN. But there is no step by step guide to follow if someone wants migrating their existing SharePoint 2007 content with existing users to the cloud and implement ADFS for the same.
Let’s consider the following situation – Fabrikam Inc. already has a Team Portal running on SharePoint 2007 with AD (NTLM) based users. These users also have their individual Mysites and profiles. Contoso Inc. a sister concern of Fabrikam Inc. recently purchased a hosting solution from 3rd party where they have options to host SharePoint 2010, SQL 2008 R2 etc. As there are some servers are available to use, Fabrikam Inc. wants to migrate their current SharePoint 2007 content into those servers. They have options to replicate their DC on this cloud environment but due to security risk they would prefer to use ADFS 2.0. They have already set up ADFS 2.0 server locally for this purpose. They also did a pilot migration with a test web application. They successfully transferred the web app from SharePoint 2007 to SharePoint 2010 and also published it into the cloud environment. But later they realized that the users cannot authenticate into the system as SharePoint considers same user coming from AD and from ADFS as two different users. It’s also impossible to find out the deep down complex permissions each users has in current environment. So they need a guidance to achieve this goal.
Let’s discuss the entire process in step by step approach.

2 Stage 1- from SharePoint 2007 to SharePoint 2010 migration

We have extensive guidance document on Technet/MSDN on this. Here is the list of articles including guidance on user profile migration we followed for the demo environment:
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=3837
http://technet.microsoft.com/library/cc263447(office.14).aspx
http://technet.microsoft.com/en-us/library/cc263299.aspx

2.1  Implement SSL

After migration to SharePoint 2010 we have demo web application running on classic NTLM based authentication. Next, we implemented SSL (required for ADFS) for both the demo web application and the web application for Mysite. We have DNS entries for both these web applications. Here is how the AAM entries look like:
 


2.2  Test User Access

We checked with random users and found their permission/access, Mysite is running well. Here is one of the permission screens:


And here is a profile view of one of the users:

3  Stage 2- AD to ADFS migration On-Premise

It’s advised to have a content database backup for both the web application at this stage as following steps are irreversible.
As the first step to migrate users from AD to ADFS, we need to transfer both the web application from Classic to Claims. Here are the PowerShell commands used for migration of both the web applications:
$WebAppName = "https://sp.fabrikam.com"
$account = "fabrikam\spadmin"
$wa = get-SPWebApplication $WebAppName
Set-SPwebApplication $wa -AuthenticationProvider (New-SPAuthenticationProvider) -Zone Default
$wa = get-SPWebApplication $WebAppName
$account = (New-SPClaimsPrincipal -identity $account -identitytype 1).ToEncodedString()
$zp = $wa.ZonePolicies("Default")
$p = $zp.Add($account,"PSPolicy")
$fc=$wa.PolicyRoles.GetSpecialRole("FullControl")
$p.PolicyRoleBindings.Add($fc)
$wa.Update()
$wa = get-SPWebApplication $WebAppName
$wa.MigrateUsers($true)
==============================================
$WebAppName = "https://mysite.fabrikam.com"
$account = "fabrikam\spadmin"
$wa = get-SPWebApplication $WebAppName
Set-SPwebApplication $wa -AuthenticationProvider (New-SPAuthenticationProvider) -Zone Default
$wa = get-SPWebApplication $WebAppName
$account = (New-SPClaimsPrincipal -identity $account -identitytype 1).ToEncodedString()
$zp = $wa.ZonePolicies("Default")
$p = $zp.Add($account,"PSPolicy")
$fc=$wa.PolicyRoles.GetSpecialRole("FullControl")
$p.PolicyRoleBindings.Add($fc)
$wa.Update()
$wa = get-SPWebApplication $WebAppName
$wa.MigrateUsers($true)
======================================================
After migration you may find users cannot access their individual Mysites. A browser refresh will help after receiving the 401 error screen to log them in.

3.1  Introduce ADFS 2.0 as Authentication Provider (Trusted Identity Provider)

We implemented ADFS 2.0 to both the web applications. Here is the PowerShell script we used in SharePoint server:
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\share\fabrikamcert.cer")

New-SPTrustedRootAuthority -Name "Token Signing Cert" -Certificate $cert

 $map = New-SPClaimTypeMapping -IncomingClaimType http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming
 $map2 = New-SPClaimTypeMapping -IncomingClaimType http://schemas.microsoft.com/ws/2008/06/identity/claims/role -IncomingClaimTypeDisplayName "Role" -SameAsIncoming
$realm = "urn:sp:fabrikam"
$ap = New-SPTrustedIdentityTokenIssuer -Name "Fabrikam ADFS Provider" -Description "SharePoint secured by SAML from Fabrikam" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map,$map2 -SignInUrl https://fabrikam-adfs.fabrikam.com/adfs/ls -IdentifierClaim "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
$uri = new-object System.Uri("https://mysite.fabrikam.com/")
$ap.ProviderRealms.Add($uri, "urn:mysite:fabrikam")
$ap.Update()
iisreset
As you can see above, we have used email address and role as incoming claim type. This will help us to identify each user and security groups. Also, we need to create two Relying Party Trusts in the ADFS server -one with identifier (“urn:sp:fabrikam” and "https://sp.fabrikam.com/_trust/") and other with (“urn:mysite:fabrikam” and https://mysite.fabrikam.com/_trust/).

 

 

Now we went ahead and add this new identity provider to both the Web Applications.




 

3.2  Migrate users from AD to ADFS

Let’s add one user and a security group coming from ADFS as members of one of the site collections to check the prefix added by claims. This is required to run the next command in PowerShell.












 



Now we deleted both the user and the group created in last step.
We created a ps1 file with following content and run it to change AD users to ADFS users for the demo web application. Make sure you keep at least one of the site collection admin ID from each site collection out of transformation in the code. This is just to keep an option open to login using Normal AD prompt in case something goes wrong:
$groupprefix = "c:0-.t|fabrikam adfs provider|"
$userprefix = "i:05.t|fabrikam adfs provider|"
$usersuffix = "@fabrikam.com" 
# Get all of the users in a web application
$url = "https://sp.fabrikam.com"
$users = Get-SPUser -web $url
# Loop through each of the users in the web app
foreach($user in $users)
{
    # Create an array that will be used to split the user name
    $a=@()
    $displayname = $user.DisplayName
    $userlogin = $user.UserLogin
    $username = “”
    if($userlogin.Contains("i:"))
#for users

    {
        $a = $userlogin.split('\')
        $username = $userprefix + $a[1] + $usersuffix
    }

elseif($userlogin.Contains("c:")) #for groups

    {
        $a = $displayname.split('\')
        $username = $groupprefix + $a[1]
    }    

if(!$userlogin.Contains("spsitecoladmin1")) #leave one of the site collection admin

    {
                #Write-Host $username         
                Move-SPUser –Identity $user –NewAlias $username -ignoresid -Confirm:$false
    }
}

3.3  Change User Profile Sync Connections

Now we removed the AD connections for User Profile Sync and added a new connection to use ADFS connection:

Also map the user properties correctly:


Next we started a full synchronization to get the user profile through. After the sync was over, we tested log-in using one of the user accounts using ADFS login prompt. User movement from demo web application to Mysite is seamless now as ADFS provide us with the WebSSO. Logout is still an issue as logging out from one Web App in the same browser window does not mean logging out from the other. We will discuss about an option to avoid this problem little later.

4   Stage 3- Migration to Cloud

Now our web applications are ready to move to cloud. We stopped SQL Server service and copied .mdf and .ldf files for both the web applications’ content database. We brought those to the SQL Server at Contoso and attached there:


4.1 Setting up the Web Applications

We then created 2 web applications with SSL and following AAM (although I used same port 7171 and 8181 for easiness of tracking but that is not mandatory):

Now we mounted the databases to the web applications after testing them:
Test-SPContentDatabase -Name "WSS_Content_7171" -WebApplication "http://appcentral:7171"
Test-SPContentDatabase -Name "WSS_Content_8181" -WebApplication "http://appcentral:8181"
Mount-SPContentDatabase -Name "WSS_Content_7171" -DatabaseServer "SQL" -WebApplication "http://appcentral:7171"
Mount-SPContentDatabase -Name "WSS_Content_8181" -DatabaseServer "SQL" -WebApplication “http://appcentral:8181

Also enabled Self-Service Site Creation option in the Web application for Mysite (8181) and checked whether managed path “/personal” is available or not.

4.2  Enabling ADFS

We used following command in the SharePoint Management Shell to enable ADFS:
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("C:\share\fabrikamcert.cer")
New-SPTrustedRootAuthority -Name "Token Signing Cert" -Certificate $cert
$map = New-SPClaimTypeMapping -IncomingClaimType http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming
$map2 = New-SPClaimTypeMapping -IncomingClaimType http://schemas.microsoft.com/ws/2008/06/identity/claims/role -IncomingClaimTypeDisplayName "Role" -SameAsIncoming
$realm = "urn:sp:contoso"
$ap = New-SPTrustedIdentityTokenIssuer -Name "Fabrikam ADFS Provider" -Description "SharePoint secured by SAML from Fabrikam" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map,$map2 -SignInUrl https://fabrikam-adfs.fabrikam.com/adfs/ls -IdentifierClaim "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
$uri = new-object System.Uri("https://mysite.fabrikam.contoso.com/")
$ap.ProviderRealms.Add($uri, "urn:mysite:contoso")
$ap.Update()
Iisreset
As shown above we used same name for the “SPTrustedIdentityTokenIssuer” as in step 3.1. Also we have 2 additional Relying Party Trusts at the ADFS server at Fabrikam:

 Also we added the new Trusted Identity provider for both Web Applications:

4.3  Finally

We then configured the User Profile Sync connection with Fabrikam ADFS server as shown in step 3.3. Now we went ahead and checked user access:





So, we were successful in migration of both the demo web application and the Mysite web application to Cloud environment and we also modified the users to use ADFS based authentication. WebSSO between these two web apps are available due to ADFS. We can additionally implement a Single Sign out option to make sure the users got sign-out from both the Web application simultaneously. There is a codeplex solution for the same. The Visual Studio solution, SingleSignOutModule in the 10SharePoint folder from http://claimsid.codeplex.com, includes a custom HTTP module to deploy to your SharePoint web application that includes this functionality.


5 Annexure

For the current setup we used SharePoint 2010 with June 2011 CU for both the environment (in Fabrikam servers and in Contoso servers). I used SQL Server 2008 R2 for both the cases.

5.1 Credits

Took help from following resources:
http://technet.microsoft.com/en-us/library/gg251985.aspx
http://technet.microsoft.com/en-us/library/ff607729.aspx
http://blog.sharepoint-voodoo.net/?p=68
http://technet.microsoft.com/en-us/library/cc263299.aspx
http://msdn.microsoft.com/en-us/library/hh446525.aspx
http://blogs.technet.com/b/speschka/archive/2010/04/27/how-to-create-multiple-claims-auth-web-apps-in-a-single-sharepoint-2010-farm.aspx
http://marcvaneijk.wordpress.com/2010/06/12/sharepoint-2010-and-adfs-2-0-the-complete-step-by-step-guide/
http://blogs.technet.com/b/speschka/archive/2010/07/30/configuring-sharepoint-2010-and-adfs-v2-end-to-end.aspx

5.2  Caveats

In step 3.3 when we changed the User Profile Sync connections from AD to ADFS, the images uploaded in the profile for the users disappear. This is because the User Profile data refreshes the content from new connections and old data got deleted. There can be alternatives to get the photos back in the User Profile although I didn’t go for it.
Moreover, we may also take backup of the User Profile DBs. This will ensure not losing the data user entered in user profile other than the data received from the AD. Because of the extra time and effort I didn’t venture the path.