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