Windows 클레임에서 SAML 클레임으로 사용자 계정 마이그레이션
Windows 클레임에서 SAML 클레임으로 사용자 계정 마이그레이션
최근 진행했던 작업에서 알게 된 사용자 중에는 일단 Windows 클레임 사용자로 시작했다가 나중에 SAML 클레임을 사용하도록 전환하는 사용자들이 많았습니다. 이 경우 Windows 클레임에서 SAML 클레임으로 계정을 손쉽게 마이그레이션할 수 있는 방법이 없다는 것이 문제입니다. 2010년 8월의 CU에 추가된 SharePoint 제품 그룹을 사용하면 MigrateUsers 메서드에서 자체 사용자 지정 코드를 실행할 수 있습니다. Bryan P. 및 Raju S.가 작성한 훌륭한 코드 샘플이 포함된 API 관련 전체 문서가 곧 제공될 예정입니다. 저의 샘플도 이 코드 샘플을 기반으로 하고 있습니다. Bryan과 Raju가 새로운 API(실제로는 IMigrateUserCallback 인터페이스)를 적절하게 문서로 작성했기 때문에 여기서는 해당 내용을 자세히 설명하지 않겠습니다. 새롭게 게시되는 정보에 대한 링크가 제공되면 해당 링크를 포함하여 이 게시물을 업데이트하겠습니다.
따라서 여기서는 평소대로 제가 작성한 사용자 지정 마이그레이션 클래스의 코드에 붙여 넣은 다음, 확인할 필요가 있는 부분에 대해 설명하겠습니다.
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("https://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;
}
}
}
먼저 전달된 SPWebApplication.AuthenticationMethod 매개 변수의 값을 확인합니다. 클레임 사용자만 변환(Windows에서 SAML로)할 것이므로 해당 작업에서만 코드를 실행하면 됩니다. 현재 사용자가 클레임 사용자이면 해당 사용자의 클레임 표현을 가져올 수 있도록 먼저 로컬 SPClaimProviderManager에 대한 참조를 가져옵니다. 이렇게 하면 사용자가 Windows 클레임 사용자인지, FBA 클레임 사용자인지 아니면 SAML 클레임 사용자인지를 확인할 수 있습니다. 여기서는 Windows 클레임 사용자만 변환할 것입니다.
클레임을 확인한 후에는 해당 클레임이 사용자용인지 그룹용인지를 확인합니다. 여기서 다소 혼란이 발생할 수 있는데요, 현재 사용자가 Windows 클레임 그룹인 경우에도 메서드로 전달되는 isGroup 매개 변수는 false로 반환됩니다. 즉, 현재 "엔터티"가 사용자인지 그룹인지를 직접 확인해야 합니다. 따라서 클레임 값을 확인해야 합니다. 엔터티가 사용자인 경우에는 도메인\사용자 형식이고, 이 형식이 아니라 SID 형식인 경우에는 엔터티가 그룹입니다.
엔터티 유형이 확인되었으면 필요한 클레임 유형을 결정할 수 있습니다. 사용자의 경우에는 ID 클레임을 만들어야 합니다. 이렇게 하려면 웹 응용 프로그램에서 사용되고 있는 SPTrustedIdentityTokenIssuer의 이름을 알아야 합니다. 이름 확인을 위한 코드를 작성할 수도 있지만, 이 코드는 샘플이므로 간단하게 유지하기 위해 클래스 생성자에 정확한 이름을 전달할 것을 지시합니다. 따라서 사용자의 로그인 이름(도메인 부분 뒤에 있음)을 가져옵니다. 이 코드의 용도상, 사용자의 전자 메일 주소는 항상 loginname@contoso.com이 됩니다. 조직에서 이러한 전자 메일 주소를 사용하지 않는 경우에는 고유한 방법으로 올바른 전자 메일 주소를 확인해야 합니다. 위의 코드에서는 이 전자 메일 주소를 사용하여 해당 사용자의 ID 클레임을 만들었습니다. 그리고 코드에서는 이 값이 반환됩니다. 즉, vbtoys\darrins 계정이 이 전자 메일 주소로 변환됩니다.
그룹의 경우에는 제공된 SID를 가져온 다음 NTAccount 클래스를 사용하여 그룹 이름을 가져옵니다. 이 이름을 사용하여 새 역할 클레임을 만든 후에, 그룹을 마이그레이션할 값으로 해당 클레임에서 인코딩된 값을 가져옵니다.
여기서는 사용자 및 그룹 둘 다에 대해 모든 항목을 자동으로 마이그레이션하지 않습니다. 서비스 계정, 기본 제공 계정 등 마이그레이션하지 않으려는 항목도 있기 때문입니다. 이러한 항목을 마이그레이션할지 여부는 요구 사항에 따라 달라집니다. 이와 같은 마이그레이션 수행 방법의 이점은 작업을 원하는 횟수만큼 수행할 수 있다는 것입니다. 사용자 하위 집합만 마이그레이션하거나 사용자를 일괄로 마이그레이션하는 등 원하는 어떤 작업이든 수행할 수 있습니다. 예를 들어 모든 사용자를 마이그레이션할 데이터베이스가 있는 경우 해당 데이터베이스를 쿼리하여 목록을 가져온 다음 마이그레이션 코드에서 각 사용자가 호출되면 사용자가 데이터베이스에서 가져온 사용자 목록에 들어 있는지를 확인하면 됩니다. 위의 코드가 이러한 마이그레이션의 한 예입니다.
앞서 언급한 것처럼, 여기서는 Bryan과 Raju가 공들여 작성한 SDK 설명서의 내용을 다루지는 않겠습니다. 그러나 여러분이 어러움을 느끼지 않도록 최소한 클래스가 호출되는 방식은 설명해야 할 것 같습니다. 이를 위해 winforms 응용 프로그램을 작성한 다음 위에서 설명한 사용자 지정 어셈블리에 대한 프로젝트 참조를 추가합니다. 이렇게 하면 매우 쉽게 빌드와 디버그를 함께 수행할 수 있습니다. 그런 후에 클래스를 호출하고 마이그레이션을 수행하는 데 사용하는 코드는 다음과 같습니다.
//get a reference to my web application
SPWebApplication wa = SPWebApplication.Lookup(new Uri("https://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);
어때요, 간단하죠? 모든 시나리오를 다루려면 이 코드를 다양하게 변형해야 할 것입니다. 그러나 이 코드를 기반으로도 간단한 작업은 수행할 수 있으며, Bryan과 Raju가 작성한 관련 설명서에서는 이 게시물의 내용보다 훨씬 많은 코드를 추가로 설명합니다.
이 문서는 현지화된 블로그 게시물입니다. 원본 문서는 Migrating User Accounts from Windows Claims to SAML Claims를 참조하십시오.