앱 간에 인증서 공유하기
사용자 ID 및 암호 조합 외 보안 인증이 필요한 UWP(유니버설 Windows 플랫폼) 앱은 인증서를 사용한 인증이 가능합니다. 인증서 인증은 사용자를 인증할 때 높은 수준의 신뢰를 제공합니다. 경우에 따라, 서비스 그룹은 여러 앱에 대해 사용자를 인증하려고 합니다. 이 문서는 동일한 인증서를 사용하여 여러 앱을 인증하는 방법 및 보안 웹 서비스에 액세스하기 위해 제공된 인증서를 사용자가 가져오기 편리한 코드를 제공하는 방법을 보여 줍니다.
앱은 인증서를 사용하여 웹 서비스에 인증할 수 있으며, 여러 앱이 인증서 저장소의 단일 인증서를 사용하여 동일한 사용자를 인증하는 것이 가능합니다. 인증서가 저장소에 없는 경우 PFX 파일에서 인증서를 불러오는 코드를 앱에 추가할 수 있습니다.
IIS(Microsoft 인터넷 정보 서비스) 및 클라이언트 인증서 매핑을 활성화 합니다.
이 문서에서는 예시 목적으로 IIS(Microsoft 인터넷 정보 서비스)를 사용합니다. IIS은 기본적으로 활성화 되어있지 않습니다. 제어판을 사용하여 IIS를 활성화 할 수 있습니다.
- 제어판을 열고 프로그램 을 선택하세요.
- Windows 기능 켜기/끄기를 선택합니다.
- 인터넷 정보 서비스 를 펼치고 나서 World Wide Web 서비스 를 펼치세요. 앱 개발 기능 을 펼치고 ASP.NET 3.5 그리고 ASP.NET 4.5 을 선택하세요. 이러한 선택들을 하고 나면 인터넷 정보 서비스 가 자동으로 활성화 됩니다.
- 확인 를 클릭하여 수정사항들을 적용합니다.
보안 웹 서비스를 생성하고 게시하세요
관리자 권한으로 Microsoft Visual Studio를 실행하고 시작 페이지에서 새 프로젝트 를 선택하세요. IIS 서버에 웹 서비스를 게시하려면 관리자 액세스가 필요합니다. 새 프로젝트 대화 상자에서 프레임워크를 .NET Framework 3.5 로 변경합니다. Visual C# ->웹 ->Visual Studio ->ASP.NET 웹 서비스 응용 프로그램을 선택합니다. 애플리케이션 이름을 "FirstContosoBank"로 지정하세요. 확인을 클릭하여 프로젝트를 만듭니다.
Service1.asmx.cs 파일에서 기본 HelloWorld 웹 메서드를 다음 "Login" 메서드로 교체하세요.
[WebMethod] public string Login() { // Verify certificate with CA var cert = new System.Security.Cryptography.X509Certificates.X509Certificate2( this.Context.Request.ClientCertificate.Certificate); bool test = cert.Verify(); return test.ToString(); }
Service1.asmx.cs 파일을 저장하세요.
솔루션 탐색기에서 "FirstContosoBank" 앱을 마우스 오른쪽 단추로 클릭하고 게시 메뉴를 선택합니다.
웹 게시 대화 상자에서 새 프로필을 생성하고 이름을 "ContosoProfile"으로 지정하세요. 다음을 클릭합니다.
다음 페이지에서 IIS 서버의 이름을 입력하고 사이트 이름을 "Default Web Site/FirstContosoBank" 로 지정합니다. 게시 를 클릭하여 웹 서비스를 게시합니다.
클라이언트 인증서 인증을 사용하도록 웹 서비스를 구성하세요.
- 인터넷 정보 서비스(IIS) 관리자를 실행하세요.
- IIS 서버 사이트를 확장하세요. 기본 웹 사이트에서 "FirstContosoBank" 웹 서비스를 선택합니다. 작업 섹션에서 고급 설정...을 선택합니다.
- 애플리케이션 풀을 .NET v2.0으로 설정하고 확인을 클릭합니다.
- IIS(인터넷 정보 서비스) 관리자에서 당신의 IIS 서버를 선택하고 서버 인증서를 더블클릭 하세요. 작업 섹션에서 자체 서명된 인증서 만들기...를 선택하고 인증서의 식별 이름으로 "ContosoBank"를 입력한 후 확인을 클릭합니다. 이렇게 하면 IIS 서버가 사용할 새 인증서가 "<서버 이름>.<도메인 이름>" 형식으로 생성됩니다.
- 인터넷 정보 서비스(IIS) 관리자에서 기본 웹 사이트를 선택하세요. 작업 섹션에서 바인딩을 선택한 다음 추가...를 클릭합니다. 유형으로 "https"를 선택하고 포트를 "443"으로 설정한 후 IIS 서버의 전체 호스트 이름("<server-name>.<domain-name>")을 입력합니다. SSL 인증서를 "ContosoBank"로 설정하세요. 확인을 클릭합니다. 닫기를 사이트 바인딩 창에서 클릭하세요.
- 인터넷 정보 서비스(IIS) 관리자에서 "FirstContosoBank" 웹 서비스를 선택하세요. SSL 설정을 더블 클릭 하세요. 필요 SSL 을 체크하세요. 클라이언트 인증서 아래에서, 필요를 선택하세요. 작업 섹션에서 적용을 클릭하세요.
- 웹 브라우저를 열고 다음 웹 주소를 입력하여 웹 서비스가 올바르게 구성되었는지 검증할 수 있습니다 "https://<서버 이름>.<도메인 이름>/FirstContosoBank/Service1.asmx". 예를 들어 " https://myserver.example.com/FirstContosoBank/Service1.asmx"입니다. 웹 서비스가 올바르게 구성된 경우 웹 서비스에 액세스하기 위하여 클라이언트 인증서를 선택하라는 메시지가 표시됩니다.
이전 단계를 반복하면 동일한 클라이언트 인증서를 사용하여 액세스할 수 있는 여러 웹 서비스를 만드는 것이 가능합니다.
인증서 인증을 사용하는 UWP 앱 만들기
이제 하나 이상의 보안 웹 서비스가 있으니 앱은 인증서를 사용하여 해당 웹 서비스에 인증할 수 있습니다. HttpClient 오브젝트를 사용하여 인증된 웹 서비스를 요청하는 경우 최초 요청에는 클라이언트 인증서가 포함되지 않습니다. 인증된 웹 서비스는 클라이언트 인증 요청으로 응답합니다. 이 경우 Windows 클라이언트는 인증서 저장소에서 사용 가능한 클라이언트 인증서를 자동으로 쿼리합니다. 사용자는 이러한 인증서 중 선택하여 웹 서비스 인증이 가능합니다. 일부 인증서는 암호로 보호되므로 사용자에게 인증서의 암호를 입력하는 방법을 제공해야 할 것입니다.
클라이언트 인증서가 없는 경우 사용자는 인증서 저장소에 인증서를 추가해야 합니다. 사용자가 클라이언트 인증서가 포함된 PFX 파일을 선택한 다음 해당 인증서를 클라이언트 인증서 저장소로 가져오는 것을 활성화 하는 코드를 앱에 포함할 수 있습니다.
팁 makecert.exe를 사용하여 이 빠른 시작에 사용할 PFX 파일을 만들 수 있습니다. makecert.exe 사용에 대한 자세한 내용은 MakeCert를 참조하세요.
Visual Studio를 열고 시작 페이지에서 새 프로젝트 만들기를 선택하세요. 새 프로젝트의 이름을 "FirstContosoBankApp" 으로 설정하세요. 확인을 클릭하여 새 프로젝트를 만듭니다.
MainPage.xaml 파일에서 기본 그리드 요소에 다음 XAML을 추가합니다. 이 XAML에는 불러올 PFX 파일을 둘러보는 버튼, 암호로 보호된 PFX 파일의 암호를 입력할 텍스트 상자, 선택한 PFX 파일을 가져오는 버튼, 보안 웹 서비스에 로그인하는 버튼 및 현재 작업의 상태를 표시하는 텍스트 블록이 포함됩니다.
<Button x:Name="Import" Content="Import Certificate (PFX file)" HorizontalAlignment="Left" Margin="352,305,0,0" VerticalAlignment="Top" Height="77" Width="260" Click="Import_Click" FontSize="16"/> <Button x:Name="Login" Content="Login" HorizontalAlignment="Left" Margin="611,305,0,0" VerticalAlignment="Top" Height="75" Width="240" Click="Login_Click" FontSize="16"/> <TextBlock x:Name="Result" HorizontalAlignment="Left" Margin="355,398,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="153" Width="560"/> <PasswordBox x:Name="PfxPassword" HorizontalAlignment="Left" Margin="483,271,0,0" VerticalAlignment="Top" Width="229"/> <TextBlock HorizontalAlignment="Left" Margin="355,271,0,0" TextWrapping="Wrap" Text="PFX password" VerticalAlignment="Top" FontSize="18" Height="32" Width="123"/> <Button x:Name="Browse" Content="Browse for PFX file" HorizontalAlignment="Left" Margin="352,189,0,0" VerticalAlignment="Top" Click="Browse_Click" Width="499" Height="68" FontSize="16"/> <TextBlock HorizontalAlignment="Left" Margin="717,271,0,0" TextWrapping="Wrap" Text="(Optional)" VerticalAlignment="Top" Height="32" Width="83" FontSize="16"/>
MainPage.xaml 파일을 저장하세요.
MainPage.cs 파일에 다음 using 문을 추가하세요.
using Windows.Web.Http; using System.Text; using Windows.Security.Cryptography.Certificates; using Windows.Storage.Pickers; using Windows.Storage; using Windows.Storage.Streams;
MainPage.xaml.cs 파일에 다음 변수들을 메인 페이지 클래스에 추가하세요. 이것들은 "FirstContosoBank" 웹 서비스의 보안 "로그인" 메서드에 대한 주소와 인증서 저장소로 가져올 PFX 인증서를 홀드하는 전역 변수를 지정합니다. <서버 이름>을 Microsoft IIS(인터넷 정보 서버) 서버를 위한 전체 주소 서버 이름으로 업데이트합니다.
private Uri requestUri = new Uri("https://<server-name>/FirstContosoBank/Service1.asmx?op=Login"); private string pfxCert = null;
MainPage.xaml.cs 파일에 로그인 버튼을 위한 클릭 처리기와 보안 웹 서비스 엑세스를 위한 메서드를 다음과 같이 추가하세요.
private void Login_Click(object sender, RoutedEventArgs e) { MakeHttpsCall(); } private async void MakeHttpsCall() { StringBuilder result = new StringBuilder("Login "); HttpResponseMessage response; try { Windows.Web.Http.HttpClient httpClient = new Windows.Web.Http.HttpClient(); response = await httpClient.GetAsync(requestUri); if (response.StatusCode == HttpStatusCode.Ok) { result.Append("successful"); } else { result = result.Append("failed with "); result = result.Append(response.StatusCode); } } catch (Exception ex) { result = result.Append("failed with "); result = result.Append(ex.Message); } Result.Text = result.ToString(); }
MainPage.xaml.cs 파일에 PFX 파일 찾아보기 버튼과, 선택된 PFX 파일을 인증서 저장소로 불러오는 버튼을 위한 다음 클릭 처리기를 다음과 같이 추가하세요.
private async void Import_Click(object sender, RoutedEventArgs e) { try { Result.Text = "Importing selected certificate into user certificate store...."; await CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync( pfxCert, PfxPassword.Password, ExportOption.Exportable, KeyProtectionLevel.NoConsent, InstallOptions.DeleteExpired, "Import Pfx"); Result.Text = "Certificate import succeeded"; } catch (Exception ex) { Result.Text = "Certificate import failed with " + ex.Message; } } private async void Browse_Click(object sender, RoutedEventArgs e) { StringBuilder result = new StringBuilder("Pfx file selection "); FileOpenPicker pfxFilePicker = new FileOpenPicker(); pfxFilePicker.FileTypeFilter.Add(".pfx"); pfxFilePicker.CommitButtonText = "Open"; try { StorageFile pfxFile = await pfxFilePicker.PickSingleFileAsync(); if (pfxFile != null) { IBuffer buffer = await FileIO.ReadBufferAsync(pfxFile); using (DataReader dataReader = DataReader.FromBuffer(buffer)) { byte[] bytes = new byte[buffer.Length]; dataReader.ReadBytes(bytes); pfxCert = System.Convert.ToBase64String(bytes); PfxPassword.Password = string.Empty; result.Append("succeeded"); } } else { result.Append("failed"); } } catch (Exception ex) { result.Append("failed with "); result.Append(ex.Message); ; } Result.Text = result.ToString(); }
앱을 실행하고 보안 웹 서비스에 로그인하고 PFX 파일을 로컬 인증서 저장소로 불러오세요.
이런 단계들을 통해 동일한 사용자 인증서를 사용하여 같은 혹은 다른 보안 웹 서비스에 액세스하는 여러 앱들을 만들 수 있습니다.