OAuth 및 SAML을 사용하여 Windows Live 및 SharePoint 2010과 페더레이션하는 유용한 방법
최초 문서 게시일: 2012년 3월 1일 목요일
많은 사용자들이 SharePoint를 Windows Live와 페더레이션하는 방법에 대해 문의해 왔습니다. 언뜻 보기에는 페더레이션이 매우 효율적인 방식일 것 같은데요. Windows Live는 사용자 수가 매우 많고 모든 사용자는 자신의 전자 메일 주소로 로그인하는데, 이는 ID 클레임으로 자주 사용되는 방식이고 폭넓게 확장 가능한 서비스이며 해당 방법(직접 또는 ACS(액세스 제어 서비스)를 통해)에 대한 지침도 다양하게 제공되고 있기 때문입니다. 그러면 굳이 Windows Live를 SharePoint와 함께 사용해야 할 필요가 있냐고요? 이전에 사용해 보셨던 분들은 아시겠지만, SharePoint를 Windows Live와 페더레이션하면 사용자 전자 메일 주소를 클레임으로 다시 가져올 수 없습니다. PUID라는 특수한 Windows Live 식별자만 제공될 뿐이죠. "PUID"는 표시 모양과 용도 면에서 볼 때 "사실상 GUID"라고 해도 과언이 아닐 것입니다.
예를 들어 SharePoint를 실제로 Windows Live와 페더레이션하는 경우 사이트에 사용자를 추가하려면 어떻게 해야 할까요? 해당 사용자의 PUID를 가져온 다음 SharePoint 그룹 또는 사용 권한 수준에 추가해야 할 것입니다. 그런데 자신의 PUID를 아는 사용자가 몇이나 될까요?(그런 분이 계시다면 남는 시간에 다른 일을 하시는 게 더 좋을 것 같은데...) 우연히 PUID를 알게 되었다고 해도 각 사이트 모음에 대한 사용자 권한을 부여할 때 PUID를 얼마나 유용하게 사용할 수 있을까요? 많은 PUID 중에서, 또는 사용자 선택 시에 원하는 사용자를 정확하게 찾아낼 수 있을까요? 거의 불가능하다고 봐야 합니다. 그래서 사용자의 혼란도 가중되는 것이겠죠.
ACS를 사용하면 보다 이상적인 솔루션을 작성할 수도 있습니다. ACS는 Windows Live, Google, Yahoo, Facebook 등의 여러 ID 공급자에 대해 특수한 기능을 제공하는 데 있어서 매우 효율적입니다. Facebook의 경우에는 실제로 OAuth를 사용하여 인증한 다음 SAML 클레임 집합을 반환하기도 합니다. 편리하겠죠? Windows Live를 통해서도 이러한 기능을 제공할 수 있습니다. Windows Live는 현재 OAuth를 지원하므로 이처럼 유용한 기능을 제공할 수 있습니다. 그런데 ACS 팀 쪽에서는 관련 정보를 제공하지 않는 것으로 보이더군요. 서론이 길었는데, 이 게시물에서는 이러한 기능을 제공하기 위한 페더레이션 방식에 대해 설명합니다.
먼저 OAuth를 사용해야 하는 이유에 대해 알아볼까요? Windows Live와 직접 페더레이션하는 경우 제공되는 PUID와는 달리, Windows Live에서 지원되는 OAuth를 사용하는 경우 사용자의 전자 메일 주소를 비롯한 훨씬 많은 정보를 파악할 수 있습니다. 저는 다음과 같은 방식을 사용했습니다.
- WIF(Windows Identity Foundation)를 사용하여 사용자 지정 ID 공급자를 작성합니다.
- STS로 리디렉션되는 사용자가 아직 인증되지 않은 경우 Windows Live로 다시 리디렉션합니다. 이렇게 하려면 Windows Live를 사용하는 "응용 프로그램"을 만들어야 하는데, 여기에 대해서는 이후에 자세히 설명하겠습니다.
- 인증된 사용자는 사용자 지정 STS로 다시 리디렉션됩니다. 다시 리디렉션된 사용자에 대한 쿼리 문자열에는 로그인 토큰이 포함되며, 이 로그인 토큰은 액세스 토큰과 교환할 수 있습니다.
- STS가 로그인 코드를 사용하여 Windows Live에 요청을 다시 수행해 액세스 토큰을 요청합니다.
- STS는 액세스 토큰을 받으면 해당 액세스 토큰으로 Windows Live에 최종 요청을 수행해 사용자에 대한 몇 가지 기본 정보를 요청합니다. 이때 반환되는 정보에 대해서도 이후에 설명하겠습니다.
- Windows Live에서 사용자 정보가 제공되면 사용자 지정 STS를 사용하여 해당 사용자에 대한 SAML 클레임 집합을 만든 다음 사용자 정보로 채웁니다. 그런 다음 응용 프로그램에서 최초에 인증을 요청한 내용을 다시 리디렉션함으로써 SAML 토큰을 사용해 필요한 작업을 수행할 수 있도록 합니다. 제 경우에는 표준 ASP.NET 응용 프로그램 및 SharePoint 2010 웹 응용 프로그램을 둘 다 사용하여 STS를 테스트했습니다.
모든 소스 코드가 이 게시물에 첨부되어 있기는 한데, 그 외에도 몇 가지 구성을 수행해야 하며 Windows Live에서 받은 응용 프로그램 ID 및 암호를 사용하여 응용 프로그램을 다시 컴파일해야 합니다. 그러나 이러한 복사 및 붙여넣기를 제외하면 실제로 작성해야 하는 코드는 없습니다. 그러면 해당 코드를 사용하는 데 필요한 사항을 살펴보겠습니다.
토큰 서명 인증서 만들기
SAML 토큰에 서명하는 데 사용할 인증서를 만들어야 합니다. 인증서에 서명하는 데 사용하는 인증서에는 개인 키가 필요하다는 것 외에는 특별한 점이 없습니다. 제 경우에는 도메인에 인증서 서비스를 설치했으므로 IIS 관리자를 열어 도메인 인증서 만들기 옵션을 선택했습니다. 마법사의 지침을 따르기만 하면 개인 키가 포함된 새 인증서가 완성됩니다. 이 프로젝트용으로는 livevbtoys라는 인증서를 만들었습니다.
다음 섹션에서도 설명하겠지만, 요청이 STS에 처음 도달할 때 사용자는 익명 사용자입니다. 앞서 만든 인증서를 사용하여 SAML 토큰에 서명을 하려면 해당 인증서의 개인 키에 대한 IIS 프로세스 액세스 권한을 부여해야 합니다. 익명 요청이 들어올 때의 IIS 프로세스 ID는 네트워크 서비스입니다. 키에 권한을 부여하려면 다음을 수행해야 합니다.
- MMC를 시작합니다.
- 인증서 스냅인을 추가합니다. 로컬 컴퓨터의 컴퓨터 저장소를 선택합니다.
- 개인 인증서 저장소를 열고 SAML 토큰 서명용으로 만든 인증서를 찾습니다. 위의 설명에 따라 인증서를 만든 경우 인증서는 기본적으로 해당 저장소에 있습니다. 인증서를 다른 방식으로 만든 경우에는 해당 저장소에 인증서를 추가해야 합니다.
- 인증서를 마우스 오른쪽 단추로 클릭하고 개인 키 관리 옵션을 선택합니다.
- 키에 대한 권한을 가진 사용자 목록에서 네트워크 서비스를 추가하고 키에 대한 읽기 권한을 부여합니다.
이 과정을 올바르게 수행하지 않으면 응용 프로그램 실행 시 "키 세트가 없습니다." 라는 오류가 표시됩니다. 이 오류는 IIS 프로세스에 개인 키에 대한 권한이 없어서 SAML 토큰에 서명을 하는 데 해당 키를 사용할 수 없다는 의미입니다.
응용 프로그램 및 필수 어셈블리 설치
응용 프로그램을 설치할 때는 IIS에서 ASP.NET 응용 프로그램을 만들어 비트를 복사한 다음 최신 버전의 WIF가 설치되어 있는지 확인합니다. 물론 서버 하나에서 응용 프로그램을 구성하고 작동하도록 설정한 후에는 하나 이상의 서버를 더 추가하여 내결함성 솔루션이 구축되었는지를 확인할 수 있습니다. 그러나 여기서는 단일 서버에서 필요한 구성만 살펴보겠습니다.
IIS에서 ASP.NET 응용 프로그램을 만드는 방법에 대해서는 설명하지 않겠습니다. 해당 작업은 Visual Studio, IIS 관리자 등을 사용하여 수행할 수 있습니다.
참고: 이 게시물에서 제공하는 코드를 사용하는 경우 Visual Studio에서 프로젝트를 열면 호스트나 사이트가 없다는 경고가 표시됩니다. 이는 제가 사용한 서버의 이름이 코드에 포함되어 있기 때문입니다. 이 문제를 해결하는 가장 쉬운 방법은 WindowsLiveOauthSts.sln 파일을 수동으로 편집한 다음 해당 파일의 https 값을 실제 환경의 값으로 변경하는 것입니다.
응용 프로그램을 실제로 만들고 나면 다음과 같은 몇 가지 작업을 수행해야 합니다.
- IIS 관리자에서 PassiveSTS.aspx를 STS 웹 사이트에 대한 기본 문서로 추가합니다.
- 익명 인증을 제외한 모든 인증 유형을 사용할 수 없도록 IIS에서 응용 프로그램에 대한 인증 설정을 변경합니다.
- STS는 SSL을 통해 실행해야 하므로 이를 위한 적절한 인증서를 얻어야 하며, 사용자 지정 STS 응용 프로그램을 사용할 IIS 가상 서버에서 바인딩을 업데이트해야 합니다.
- 신뢰 당사자 web.config의 trustedIssuers 섹션에 있는 add 요소의 thumbprint 특성에 토큰 서명 인증서의 지문을 추가해야 합니다(테스트 시 SharePoint를 사용하지 않는 경우). Visual Studio의 STS 참조 추가 마법사를 사용하는 경우에는 해당 작업이 자동으로 수행됩니다.
IIS에서는 이러한 구성 작업만 수행하면 됩니다.
사용자 지정 STS 프로젝트 업데이트 및 빌드
이 게시물에 첨부된 zip 파일에는 WindowsLiveOauthSts라는 Visual Studio 2010 프로젝트가 들어 있습니다. 위에서 설명한 대로 IIS를 구성하고 WindowsLiveOauthSts.sln 파일을 업데이트한 후에는 Visual Studio에서 프로젝트를 열 수 있습니다. 가장 먼저 수행해야 하는 작업은 PassiveSTS.aspx.cs 클래스의 CLIENT_ID 및 CLIENT_SECRET 상수를 업데이트하는 것입니다. 이러한 상수는 새 Windows Live 응용 프로그램을 만들면 생성됩니다. 이 게시물에서는 상수 업데이트 작업의 단계에 대해서는 다루지 않습니다(Windows Live 팀에서 관련 정보를 제공함). Windows Live 응용 프로그램은 https://manage.dev.live.com/Applications/Index?wa=wsignin1.0(영문일 수 있음)에서 만들 수 있습니다. 또한 응용 프로그램을 만들 때는 리디렉션 도메인을 https://myserver.foo.com과 같이 사용자 지정 STS가 호스팅되는 위치로 설정해야 합니다.
이제 ID와 암호가 있으므로 응용 프로그램에서 다음 항목을 업데이트합니다.
- PassiveSTS.aspx.cs 클래스에서 CLIENT_ID 및 CLIENT_SECRET 상수를 업데이트합니다.
- web.config 파일에서 appSettings 섹션의 SigningCertificateName을 업데이트합니다. IssuerName 설정은 반드시 변경할 필요는 없지만 원하는 경우에는 변경할 수 있습니다.
- STS 프로젝트의 FederationMetadata.xml 문서에 대한 토큰 서명 인증서를 업데이트합니다. 사용할 인증서를 선택하고 나면 이 게시물에 포함된 test.exe 응용 프로그램을 사용하여 인증서의 문자열 값을 가져올 수 있습니다. 이 값을 복사하여 federationmetadata.xml의 X509Certificate 요소 값을 대체해야 합니다.
한 가지 사항을 더 언급하고 넘어가겠습니다. CustomSecurityTokenService.cs 파일에서는 enableAppliesToValidation이라는 변수를 true로 설정한 다음 해당 사용자 지정 STS를 사용할 수 있는 URL 목록을 제공할 수 있습니다. 제 경우에는 사용자 지정 STS를 이처럼 제한하지 않기로 하여 변수를 false로 설정했습니다. 사용자 지정 STS를 잠그려는 경우에는 이 시점에서 해당 변수를 true로 설정하면 됩니다. 이러한 변경 작업을 모두 수행하고 나면 응용 프로그램을 다시 컴파일하고 사용할 수 있습니다.
아, 한 가지만 더 말씀드릴게요. 이 프로젝트를 빌드하는 중에 테스트에 사용했던 예제 ASP.NET 응용 프로그램도 게시물에 첨부되어 있습니다. 이 응용 프로그램은 LiveRP라는 프로젝트에 포함되어 있습니다. 여기서 해당 프로젝트에 대해서는 별도로 설명하지 않겠으며, 테스트 시 사용할 수 있다는 정도만 언급하겠습니다. 위에서 설명한 대로 STS 토큰 서명 인증서의 지문만 변경하면 됩니다.
SharePoint 구성
이제 모든 항목이 구성되었으며 사용자 지정 STS는 정상적으로 작동합니다. 남은 작업은 SharePoint에서 새 SPTrustedIdentityToken 발급자를 만든 다음 해당 발급자를 사용하도록 새/기존 웹 응용 프로그램을 구성하는 것뿐입니다. SPTrustedIdentityTokenIssuer 구성 시에는 몇 가지 사항을 기억해야 합니다. 여기서는 제가 발급자를 만들 때 사용했던 PowerShell을 제공하고 각 항목에 대해 설명하겠습니다.
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\livevbtoys.cer")
New-SPTrustedRootAuthority -Name "SPS Live Token Signing Certificate" -Certificate $cert
$map = New-SPClaimTypeMapping -IncomingClaimType "https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress" -IncomingClaimTypeDisplayName "EmailAddress" -SameAsIncoming
$map2 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/id" -IncomingClaimTypeDisplayName "WindowsLiveID" -SameAsIncoming
$map3 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/full_name" -IncomingClaimTypeDisplayName "FullName" -SameAsIncoming
$map4 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/first_name" -IncomingClaimTypeDisplayName "FirstName" -SameAsIncoming
$map5 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/last_name" -IncomingClaimTypeDisplayName "LastName" -SameAsIncoming
$map6 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/link" -IncomingClaimTypeDisplayName "Link" -SameAsIncoming
$map7 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/gender" -IncomingClaimTypeDisplayName "Gender" -SameAsIncoming
$map8 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/locale" -IncomingClaimTypeDisplayName "Locale" -SameAsIncoming
$map9 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/updated_time" -IncomingClaimTypeDisplayName "WindowsLiveLastUpdatedTime" -SameAsIncoming
$map10 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/account" -IncomingClaimTypeDisplayName "AccountName" -SameAsIncoming
$map11 = New-SPClaimTypeMapping -IncomingClaimType "https://blogs.technet.com/b/speschka/claims/accesstoken" -IncomingClaimTypeDisplayName "WindowsLiveAccessToken" -SameAsIncoming
$realm = "https://spslive.vbtoys.com/_trust/"
$ap = New-SPTrustedIdentityTokenIssuer -Name "SpsLive" -Description "Window Live oAuth Identity Provider for SAML" -realm $realm -ImportTrustCertificate $cert -ClaimsMappings $map,$map2,$map3,$map4,$map5,$map6,$map7,$map8,$map9,$map10,$map11 -SignInUrl "https://spr200.vbtoys.com/WindowsLiveOauthSts/PassiveSTS.aspx" -IdentifierClaim "https://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
여기서 기억해야 할 사항은 다음과 같습니다.
- 위에서 설명한 것처럼, 토큰에 서명하는 데 사용할 livevbtoys.cer 인증서를 만들었으므로 SPTrustedRootAuthority 목록에 해당 인증서를 추가한 다음 토큰 발급자와 연결했습니다.
- 사용자 지정 STS에서 반환하는 모든 클레임에 대해 클레임 매핑을 만들었습니다. 위에 나와 있는 것처럼, Windows Live로 직접 페더레이션하는 경우에 비해 훨씬 많고 효율적인 매핑이 제공됩니다. 여기서 추가로 언급하고 싶은 한 가지 사항은, Windows Live에서 가져온 액세스 토큰도 클레임으로 포함했다는 것입니다. Facebook에서는 이러한 방식이 문제 없이 작동했는데, 아직 테스트는 하지 못했으므로 Windows Live에서 클레임을 다시 사용할 수 있는지는 확실치 않습니다. 이후에 기회가 되면 별도의 게시물에서 이에 관해 설명하도록 하겠습니다.
- $realm 값은 매우 중요합니다. 이 값은 웹 응용 프로그램의 루트 사이트를 가리켜야 하며, /_trust/ 디렉터리를 포함해야 합니다. 이 값을 잘못 설정하면 인증 후 다시 리디렉션될 때 SharePoint에서 500 오류가 발생합니다.
- 토큰 발급자를 만들 때 사용하는 –SignInUrl 매개 변수는 사용자 지정 STS의 PassiveSTS.aspx 페이지에 대한 절대 URL입니다.
별로 어려울 건 없죠? 이렇게 설정한 후에도 기본 제공되는 사용자 선택 및 클레임 공급자를 계속 사용하므로 조회 기능은 제공되지 않습니다. 그리고 사용자가 Windows Live에 로그인할 때 사용하는 전자 메일 주소를 사용하여 해당 사용자에 대한 권한을 부여합니다. 실제로 이 예를 확장하여 https://blogs.msdn.com/b/sharepoint_ko/archive/2012/03/07/sharep-oint-azure-1.aspx 블로그 게시물에서 설명했던 Azure 클레임 공급자를 사용할 수도 있습니다. 즉, 이 STS를 사용하여 Windows Live를 통해 인증하고 실제 SAML 클레임을 가져온 다음 Azure 사용자 지정 클레임 공급자 프로젝트를 통해 인증된 사용자를 Azure 디렉터리 저장소 및 사용자 선택에 추가하여 선택할 수 있습니다.
아래 그림에서 보시다시피, SharePoint 사이트를 처음 방문하여 Windows Live를 통해 인증할 때는 다음과 같은 화면이 표시됩니다.
처음 로그인하면 사용자 지정 STS 응용 프로그램과 정보를 공유할지 묻는 화면이 표시됩니다. 이는 표준 OAuth 사용 권한 확인 절차이므로 신경 쓰지 않아도 됩니다. 아래 화면에는 제가 STS에 표시하도록 요청한 데이터가 나와 있습니다. 각자 원하는 데이터 집합이 표시되도록 설정할 수 있습니다. 다른 데이터 집합을 표시하기 위해 변경해야 하는 항목 및 변경 방법을 확인하려면 Windows Live OAuth SDK를 참조하십시오.
액세스가 허용되면 SharePoint 사이트로 리디렉션됩니다. 이 예에서는 https://blogs.technet.com/b/speschka/archive/2010/02/13/figuring-out-what-claims-you-have-in-sharepoint-2010.aspx(영문일 수 있음) 블로그 게시물에서 설명했던 SharePoint 클레임 웹 파트를 사용합니다. 보시다시피 OAuth를 통해 Windows Live에서 가져온 모든 클레임이 표시됩니다. 사용자 지정 STS를 만들고, 이 프로젝트용으로 만든 Windows Live 전자 메일 주소를 사용하여 로그인(오른쪽 위의 로그인 컨트롤 사용)했기 때문에 이러한 클레임은 SAML 클레임으로 제공됩니다.
이 문서는 번역된 블로그 게시물입니다. 원본 문서는 Finally A USEFUL Way to Federate With Windows Live and SharePoint 2010 Using OAuth and SAML을 참조하십시오.