3.2 Managed Card 발행에 대한 Microsoft 예제 실습 (2) - STS 구현
지난 토픽 "3.1 Managed Card 발행에 대한 Microsoft 예제 실습(1) - CardWriter"에서는 Identity Provider(이하, IP)가 제공해야 할 서비스의 하나인 카드를 발행하는 것에 대해 살펴봤었는데요. 이번 회에서는 Security Token Service(이하, STS)를 구현하는 것에 대해 알아보겠습니다.
이번에도 역시 Microsoft에서 제공되는 예제를 통해서 실습을 해볼텐데요. 이번 예제는, 다음의 URL에서 다운로드 받을 수 있습니다. (아쉽게도, VB.NET용 예제는 제공되지 않고 있군요.)
Sample Simple-STS for RC1+ in C#
; http://cardspace.netfx3.com/files/folders/samples_rc_1/entry6082.aspx
위의 URL을 방문하시면, "Simple STS.zip" 파일을 다운로드할 수 있으며, 그것을 기준으로 설명을 해나갈 것입니다. 이번 예제 역시, zip 파일 안의 "Simple-STS.doc", "Installation-Instructions.doc", "Creating Managed Cards.doc" 파일을 이용해서 실습해 볼 수 있으며, 단지 저는 간략화된 설명과 약간의 사견을 곁들여서 설명하는 것입니다.
[테스트 웹 사이트 설치]
1. 다운로드 받은 "Simple STS.zip" 파일의 압축을 "C:\Net30\STS" 폴더에 풀어 놓습니다. 다음과 같은 구조를 예로 들겠습니다.

2. 역시 이번에도 "자동화된 셋업"보다는 가능한 수작업으로 설치를 해보겠습니다. 우선, 웹 사이트의 가상 디렉터리 먼저 설정을 해볼 텐데요. 다음과 같이 3개의 가상 디렉터리 설정을 합니다.
CardSpace: C:\Net30\STS\website\CardSpace
images: C:\Net30\STS\website\images
crldata: C:\Net30\STS\website\crldata
따라서, IIS 관리자에는 다음과 같이 보여져야 합니다.

3. "C:\WINDOWS\system32\drivers\etc" 폴더의 "hosts" 파일에 다음과 같은 이름을 추가합니다.
127.0.0.1 www.adatum.com adatum.com
127.0.0.1 www.contoso.com contoso.com
127.0.0.1 www.fabrikam.com fabrikam.com
127.0.0.1 www.woodgrovebank.com woodgrovebank.com
4. 인증서 설치 부분은 배치 스크립트 파일을 이용하겠습니다. "C:\Net30\STS\scripts" 폴더에 있는 "Install-certificates.vbs" 파일을 두 번 눌러서 실행시킵니다. 실행하고 난 후, 약간 시간이 걸리므로 "Certificate Installation Script executed successfully"라는 메시지가 나올 때까지 기다려 주십시오.
5. "CardSpace" 가상 디렉터리를 포함하는 웹 사이트에 "www.fabrikam.com" SSL 인증서를 설치합니다. 이 부분에 대해서는 "1. 개인 발행 카드에 대한 Microsoft 예제 실습" 단계 7번을 참고하십시오.
6. 웹 사이트를 구동하는 작업자 프로세스의 계정을 편의상 "SYSTEM"으로 바꿔줍니다. (테스트임에도 불구하고 계정을 바꾸고 싶지 않은 분이라면 "C:\Net30\Managed\documents\Installation-Instructions.doc" 파일의 "IIS: ACLs for Certificate Private Keys" 부분을 참고해서 설정을 해주시면 됩니다.)
7. 마지막으로 정상적으로 설치가 되었는지 다음과 같은 URL로 방문해봅니다. 정상적으로 화면이 나와야 합니다.
1. http://www.fabrikam.com/images/fabrikam.gif
2. https://www.fabrikam.com/CardSpace/
[STS 빌드 및 실행]
STS 기본 예제는 대강의 뼈대만 제작되어져 있는 상태일 뿐, 현실적으로 사용하기에는 아직 예제 코드가 많지 않은 상태입니다. 아마도, 이 부분은 점차로 개선된 소스가 공개될 거라 개인적으로 예상해 봅니다. 일단 여기서는 실습이 가능한 상태까지만 만들어 두겠습니다.
1. "C:\Net30\STS\SecurityTokenServer" 폴더에 있는 "SampleSecurityTokenService.csproj" 파일을 VS.NET 2005에서 열고, "RequestSecurityTokenResponse.cs" 파일의 "GetTokenAttributes" 메서드를 다음과 같이 수정합니다.
protected List<SamlAttribute> GetTokenAttributes()
{
List<SamlAttribute> result = new List<SamlAttribute>();
string ppid = "your ppid";
result.Add(new SamlAttribute(new Claim(ClaimTypes.PPID, ppid, Rights.PossessProperty)));
result.Add(new SamlAttribute(new Claim(ClaimTypes.GivenName, "SeongTae", Rights.PossessProperty)));
result.Add(new SamlAttribute(new Claim(ClaimTypes.Surname, "Jeong", Rights.PossessProperty)));
result.Add(new SamlAttribute(new Claim(ClaimTypes.Email, "kevin13@chol.net", Rights.PossessProperty)));
return result;
}
2. 빌드를 하고, 결과물이 "C:\Net30\STS\bin"에 생성되었는지 확인합니다.
3. "C:\Net30\STS\bin\SampleSecurityTokenService.exe"를 실행시킵니다. 다음과 같은 Console 화면이 나와야 합니다.
Listener = http://www.fabrikam.com:7000/sample/trust/smartcard/sts, State = Opened
Listener = https://www.fabrikam.com:7001/sample/trust/smartcard/mex, State = Opened
Listener = http://www.fabrikam.com:7000/sample/trust/smartcard, State = Opened
Listener = http://www.fabrikam.com:7000/sample/trust/selfissuedsaml/sts, State = Opened
Listener = https://www.fabrikam.com:7001/sample/trust/selfissuedsaml/mex, State = Opened
Listener = http://www.fabrikam.com:7000/sample/trust/selfissuedsaml, State = Opened
Listener = http://www.fabrikam.com:7000/sample/trust/usernamepassword/sts, State = Opened
Listener = https://www.fabrikam.com:7001/sample/trust/usernamepassword/mex, State = Opened
Listener = http://www.fabrikam.com:7000/sample/trust/usernamepassword, State = Opened
Press to terminate services
4. 위의 "Listener" 주소에서 보시는 것처럼, "https://www.fabrikam.com:7001"에 대해서는 WCF가 "HTTPS" 프로토콜을 사용함을 알 수 있습니다. 따라서, 7001 포트에 대해 SSL 인증서를 매핑시켜 줘야 하는데, 다음과 같은 HttpCfg.exe를 사용하시면 됩니다. 참고로, "httpcfg.exe" 파일은 "C:\Net30\STS\HttpCfg\httpcfg.vcproj" VC++ 프로젝트를 빌드하면 "C:\Net30\STS\bin" 폴더에 생성됩니다.
httpcfg set ssl -i 0.0.0.0:7001 -h d47de657fa4902555902cb7f0edd2ba9b05debb8
위의 사항과 관련된 좀 더 자세한 사항은 다음의 토픽을 참고하십시오.
[WCF 이야기] : 3.8.1 WCF에 SSL 적용 (1) - Httpcfg.exe 도구를 이용한 SSL 설정
; https://www.sysnet.pe.kr/2/0/389
[Managed Card 발행]
여기 예제에서는 Managed Card를 Personal Card 기반 위에서 만들게 되는데요. 다음과 같은 순서로 따라해 주시면 됩니다.
1. "https://www.fabrikam.com/CardSpace/Sample.htm"로 방문합니다. 해당 페이지에서 "Click here to get the token" 버튼을 누릅니다.
2. 그럼, 다음과 같이 카드를 선택하는 창이 뜹니다. 카드가 하나도 없는 분은 새로 "Personal Card"를 만듭니다. 여기서는 아래의 카드 중에서 "Test"를 선택해서 "Send" 버튼을 누르겠습니다.

3. 그러면 다음과 같이 Card가 전송한 내용을 XML로 보여줍니다.

4. 개인 카드를 기반으로 Managed Card를 만들기 위해 필요한 값은 단 하나, "PPID" 값입니다. "Click here to send the card to the server" 버튼을 눌러서 해당 XML로부터 PPID 값을 구해냅니다.

5. 위에서 구한 PPID 값 "748IqwQEn/Wn29+VJhjtcneJLBzWKcuqCBRn5ikHw8I="을 복사해서, "C:\Net30\STS\SampleCards\FabrikamSelfIssued.ini" 파일의 "[Credentials]" 부분을 다음과 같이 편집해 줍니다.
** 주의: 아래의 value 값은 반드시 여러분들이 구한 값이어야 합니다.
[Credentials]
value=748IqwQEn/Wn29+VJhjtcneJLBzWKcuqCBRn5ikHw8I=
Hint=
6. CardWriter.exe를 이용하여 5번 단계에서 편집된 "C:\Net30\STS\SampleCards\FabrikamSelfIssued.ini" 설정값으로부터 "Managed Card"를 생성해 냅니다.
C:\Net30\STS>.\bin\cardwriter.exe .\samplecards\FabrikamSelfIssued.ini
Reading card config from
C:\Net30\STS\samplecards\FabrikamSelfIssued.ini
Card written to
C:\Net30\STS\samplecards\FabrikamSelfIssued.crd
7. 출력된 "FabrikamSelfIssued.crd" Managed Card 파일을 두 번 클릭해서 다음 화면과 같이 설치를 할 수 있습니다.

[최종 실습]
자, 이제 모든 준비는 끝났습니다. 사용자는 정상적으로 클라이언트 측 컴퓨터에 "Managed Card"를 설치해 놓았고, 해당 Managed Card는 다음과 같은 정보를 포함하고 있습니다.
- 서버의 공개키만을 가지고 있는 인증서
- STS(Security Token Service)의 Endpoint 주소
- MEX(Metadata Exchange)의 Endpoint 주소
- 카드에 보여질 그림 데이터
- Identity Provider로 조회해 올 "필수 필드" / "조건 필드"의 목록
- 인증 유형 (UserNamePassword, KerberosAuth, SelfIssuedAuth, SmartCard)
- Card ID
다음은 이 Managed Card로 실습을 테스트 해보는 과정입니다.
1. SampleSecurityTokenService.exe가 실행되어져 있는지 확인합니다.
2. "https://www.fabrikam.com/CardSpace/Sample.htm"을 방문해서 "Click here to get the token."을 선택합니다. 그럼 다음과 같이 "Windows CardSpace"가 구동되고, 어떤 카드를 선택할 지 물어옵니다. "My Card(self-backed)" 카드를 선택하고, 우측 하단의 "Preview" 버튼을 눌러봅니다.

3. 아래와 같이 화면이 나오게 되고, 이 카드를 통해 어떤 사용자 정보를 IP에 요청할 것인지에 대한 항목들을 볼 수 있습니다. 카드 자체에는 요청 목록만 존재할 뿐 값이 없기 때문에 아래 그림에서 보는 것처럼 비어 있는 체로 나옵니다. 그 외에 "Personal Card"와 구분되는 또 한 가지 사항은 우측 하단에 "Retrieve" 버튼이 있다는 것입니다. 테스트 삼아서 이 버튼을 한번 눌러봅니다.

4. 이 과정에서 만약 STS(Security Token Service)가 정상적으로 구성이 되었다면, 통신이 오고 가는 대화창이 뜨고 난후 "Retrieve" 버튼이 "disable" 상태로 바뀌게 됩니다. 만약 오류가 있다면, 값을 구해올 수 없다는 오류 창을 내므로 반드시 이 과정에서 문제를 확인해 주어야 합니다. (이벤트 로그를 참고하십시오.) 한 가지 의아스러운 것은, 정상적인 통신이 이루어진 후에 정작 "Retrieve" 버튼의 의미와는 달리 구해온 값들이 화면에 표시되지 않는다는 것입니다. (여전히 비어있습니다.)
5. "Send" 버튼을 눌러주고 나면 브라우저 화면으로 돌아오게 되고, 계속해서 "Click here to send the card to the server" 버튼을 눌러 주면, 다음과 같은 결과 화면을 볼 수가 있습니다.

이것으로 "Windows CardSpace"에 대한 여정을 마치게 되었습니다. 개인적으로 실습을 진행하면서 STS 프로젝트에 아쉬운 점들이 눈에 띄더군요. 예를 들어, 사용자로부터의 필수/조건 필드에 대한 요청 및 Card ID에 따라서 사용자 정보를 적절하게 출력해 주는 루틴이 있어야 하는데 아쉽게도 "RequestSecurityToken.cs" 예제에서는 Card Id를 구하는 부분조차도 구현이 안된 상태였습니다. (만약 여러분들이 지금 바로 managed card를 실전 배치하시겠다면 "약간의 수고"를 들여서 그 부분에 대한 코드를 만들어 주셔야 합니다.) 아마도 .NET 3.0 정식 버전 출시 이후에는 그러한 부분의 코드들이 많이 보강된 예제가 나오지 않을까 생각해 봅니다.
다음 토픽에서는, 부록으로 ^^ 제 SYSNET 웹 사이트에 "Windows CardSpace"를 이용하여 로그인하는 방법을 소개해 드리도록 하겠습니다.
[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]