Thursday, March 10, 2011

Blog Post: Migrando contas de usu�rio das Declara��es do Windows para as Declara��es SAML

Migrando contas de usu�rio das Declara��es do Windows para as Declara��es SAML

No trabalho que estou fazendo no momento, tenho visto muita gente interessada em come�ar a usar declara��es do Windows e mais adiante passar para declara��es SAML.  Parece razo�vel, mas o problema � que n�o tenho uma forma autom�tica de migrar contas das declara��es do Windows para declara��es SAML.  A boa not�cia � que o grupo de produtos do SharePoint fez uma atualiza��o na CU de agosto de 2010 para permitir que voc� execute seu pr�prio c�digo personalizado no m�todo MigrateUsers.  Temos um documento completo sobre a API que ser� lan�ado brevemente, junto com um exemplo de c�digo que foi resultado de um �timo trabalho de Bryan P. e Raju S., e meu exemplo � baseado nisso.  Eles fizeram um excelente trabalho na documenta��o da nova API (na verdade, uma interface,IMigrateUserCallback), portanto n�o entrarei em muitos detalhes aqui.  Assim que eu tiver um link para as informa��es rec�m-publicadas sobre isso, atualizarei esta postagem com ele.

Portanto, como sempre, vou come�ar apenas colando o c�digo da minha classe de migra��o personalizada e percorrerei as partes que acho interessantes.

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Diagnostics;

using System.Security;

using System.Security.Principal;

//add references to Microsoft.SharePoint and Microsoft.IdentityModel for these

using Microsoft.SharePoint;

using Microsoft.SharePoint.Administration;

using Microsoft.SharePoint.Administration.Claims;

using Microsoft.IdentityModel.Claims;

 

 

namespace MigrateUserSample

{

   public class MigrateTest : IMigrateUserCallback

   {

 

       public string SPTrustedIdentityTokenIssuerName { get; set; }

 

 

       public MigrateTest(string TrustedIdentityTokenIssuerName)

       {

          SPTrustedIdentityTokenIssuerName = TrustedIdentityTokenIssuerName;

       }

 

 

       public string ConvertFromOldUser(string oldUser,

              SPWebApplication.AuthenticationMethod authType, bool isGroup)

       {

          string value = string.Empty;

 

          try

          {

              switch (authType)

              {

                 case SPWebApplication.AuthenticationMethod.Windows:

                     //code for converting from classic Windows would be here

                     Debug.WriteLine(oldUser);

                     break;

                 case SPWebApplication.AuthenticationMethod.Claims:

                     //this is the only scenario this sample will cover

                     //migrating from Windows claims to SAML claims

                     Debug.WriteLine(oldUser);

 

                     //get the claim provider manager

                     SPClaimProviderManager cpm = SPClaimProviderManager.Local;

 

                     //create a claim from the identifier so we can see if the

                     //original issuer came from Windows

                     SPClaim idClaim = cpm.ConvertIdentifierToClaim(oldUser,

                           SPIdentifierTypes.EncodedClaim);

 

                     //this is a Windows claims user, and we are going to

                     //convert to a SAML claims user

                     if (idClaim.OriginalIssuer == "Windows")

                     {

                        //windows claims users will be in the format domain\user;

                        //windows claims groups will be in the SID format

                        if (idClaim.Value.Contains("\\"))

                        {

                           //migrating a user

 

                           //you will want to check the identity of the user here

                           //there may be some Windows claims accounts you don't want to

                           //convert yet, and there will also be service accounts that

                           //are passed in that you may not want to convert either; 

                           //ideally you would just read from a data source to determine

                           //which users you should convert, and then check the identity

                           //here to see if it's one of the users that should be

                           //converted

 

                           //in this case, I'm only converting one user - darrins

                           if (idClaim.Value == "contoso\\darrins")

                           {

                               //I’m getting an identity claim here, grabbing the

                               //part after the "domain\", and appending the email

                               //suffix to it, so it becomes darrins@contoso.com

                               SPClaim migratedUserClaim =

                                         SPClaimProviderManager.CreateUserClaim(

                                         idClaim.Value.Split('\\')[1] + "@contoso.com",

                                         SPOriginalIssuerType.TrustedProvider,

                                         SPTrustedIdentityTokenIssuerName);

 

                               //get the encoded value of what the new identity

                               //claim will be

                               value = migratedUserClaim.ToEncodedString();

                           }

                        }

                        else

                        {

                           //migrating a group

 

                           //get the plain name of the group

                           SecurityIdentifier sid =

                               new SecurityIdentifier(idClaim.Value);

                           NTAccount groupAccount =

                               (NTAccount)sid.Translate(typeof(NTAccount));

 

                           string groupName = groupAccount.ToString();

 

                           //only interested in migrating the Portal People group

                           if (groupName.ToLower() == "contoso\\portal people")

                           {

                               //create a new role claim

                               SPClaim migratedGroupClaim =

                                  new SPClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role",

                                  groupName.Split('\\')[1],

                                  Microsoft.IdentityModel.Claims.ClaimValueTypes.String,

                                  SPOriginalIssuers.Format(

                                  SPOriginalIssuerType.TrustedProvider,

                                  SPTrustedIdentityTokenIssuerName));

 

                               //get the encoded value of what the new role claim will be

                               value = migratedGroupClaim.ToEncodedString();

                           }

                        }

                     }

 

                     break;

                 case SPWebApplication.AuthenticationMethod.Forms:

                     //code for converting from Forms would be here

                     Debug.WriteLine(oldUser);

                     break;

              }

          }

          catch (Exception ex)

          {

              Debug.WriteLine(ex.Message);

          }

 

          return value;

       }

   }

}

 

 

A primeira coisa que estou fazendo � verificar o valor do par�metro SPWebApplication.AuthenticationMethod que foi passado.  Como estou apenas interessado em converter usu�rios de declara��es (Windows para SAML), esta � a �nica situa��o em que tenho um c�digo para executar.  Quando o usu�rio atual � um usu�rio de declara��es, come�o obtendo uma refer�ncia ao SPClaimProviderManager local para obter uma representa��o de declara��o do usu�rio.  Fa�o isso para determinar se o usu�rio � um usu�rio de declara��o do Windows, de declara��es FBA ou de declara��es SAML.  Em meu caso, apenas quero converter usu�rios de declara��es do Windows. 

 

Depois que eu determinar que tenho um usu�rio de declara��es do Windows, a pr�xima coisa a fazer � descobrir se a declara��o � de um usu�rio ou grupo.  Aqui est�o algumas coisas estranhas que voc� pode perceber.  Mesmo quando o usu�rio atual � um grupo de declara��es do Windows, o par�metro isGroup que � passado para o m�todo retorna falso.  Isso significa que preciso verificar eu mesmo se a “entidade” atual � um usu�rio ou grupo.  Portanto, apenas observo o valor da declara��o. Se for um usu�rio, ela estar� no formato dom�nio\usu�rio; caso contr�rio, trata-se de um grupo, que estar� em um formato SID.

Agora que sei qual � o tipo de entidade, posso determinar que tipo de declara��o � necess�ria.  Para um usu�rio, preciso criar uma declara��o de identidade.  Uma das coisas que preciso saber � o nome do SPTrustedIdentityTokenIssuer que est� sendo usado no aplicativo Web.  Eu poderia ter escrito um c�digo para descobrir isso, mas em vez disso, “parti do princ�pio de que era um exemplo, me processe por ser pregui�oso” e for��-lo a fornecer o nome correto no construtor da minha classe.  Portanto, pego o nome de logon do usu�rio (depois da parte do dom�nio) e para mim o endere�o de email dele ser� sempre loginname@contoso.com.  Se a sua organiza��o n�o for essa, voc� precisar� descobrir por si mesmo para determinar o endere�o de email correto.  Eu uso esse endere�o com o c�digo acima para criar uma declara��o de identidade para esse usu�rio, e esse � o valor que retorno, neste caso, aquele para o qual a conta vbtoys\darrins ser� convertida.  (regra de gram�tica: n�o me perturbe por terminar a minha frase em uma preposi��o)

Para grupos, pego o SID que recebe e uso a classe NTAccount para obter o nome amig�vel do grupo.  Uso isso para criar uma nova declara��o de fun��o e retiro o valor codificado como o valor para o qual o grupo deve ser migrado.  (regra de gram�tica: feliz agora, sim?!?)

Uma outra coisa a se notar, para os usu�rios e grupos, � que n�o tento migrar tudo automaticamente.  H� algumas coisas que talvez eu n�o queira migrar, como contas de servi�o, contas internas, etc.; se voc� vai querer migrar ou n�o depende das suas necessidades.  O que � bom nesse m�todo de migra��o � que voc� pode faz�-lo quantas vezes quiser.  Se voc� quiser migrar apenas um subconjunto de usu�rios, ou fazer isso em lotes, ou durante um tempo, ou o que quiser; � poss�vel faz�-lo.  Por exemplo, voc� pode ter um banco de dados com os usu�rios que deseja migrar.  Voc� poderia consult�-lo para obter a lista e quando cada usu�rio fosse chamado no c�digo de migra��o, voc� poderia ver se ele est� na lista de usu�rios do seu banco de dados.  Isso � apenas um exemplo.

OK, n�o quero entrar muito em detalhes sobre a documenta��o de SDK que Bryan e Raju fizeram, mas me sinto tentado a pelo menos inform�-lo como a sua classe � chamada, portanto, n�o vou deixar voc� perdido por aqui.  O que fiz foi apenas escrever um aplicativo winforms e adicionar uma refer�ncia de projeto ao meu assembly personalizado descrito acima.  Isso tornou extremamente f�cil compilar e depilar ao mesmo tempo.  O c�digo que uso para invocar a minha classe e fazer a migra��o se parece com o seguinte:

 

//get a reference to my web application

SPWebApplication wa = SPWebApplication.Lookup(new Uri("http://foo"));

 

//this is the name of my trusted identity token issuer

string SPTrustedIdentityTokenIssuerName = "ADFSProvider";

 

//create an instance of the custom migrate user callback class

MigrateUserSample.MigrateTest mt =

new MigrateUserSample.MigrateTest(SPTrustedIdentityTokenIssuerName);

 

//create an interface reference to it

IMigrateUserCallback muc = mt as IMigrateUserCallback;

 

//migrate the users with it

wa.MigrateUsers(muc);

 

� isso a�.  Haver� muitas outras varia��es disso necess�rias para cobrir todos os cen�rios, mas este � um bom come�o, e Bryan e Raju far�o acr�scimos significativos nesse trabalho.

Esta � uma postagem de blog localizada. O artigo original est� em Migrating User Accounts from Windows Claims to SAML Claims

Eva Green Lauren Conrad Arielle Kebbel Jessica Paré Leelee Sobieski

No comments:

Post a Comment