Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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를 참조하십시오.