자격 증명 보관: Windows 스토어 앱의 사용자 이름과 암호 처리를 위한 솔루션
아직도 Windows 스토어 앱에서 사용 가능한 자격 증명 보관에 대해서 들어본 적이 없으십니까? 그렇다면 이 글을 꼭 보셔야 합니다. 왜냐하면 자격 증명 보관을 이용하면 사용자 자격 증명의 저장 및 검색 작업이 간편해질 뿐만 아니라 자격 증명을 안전하게 저장할 수 있기 때문입니다. 또한 사용자는 자격 증명을 '무료로' Microsoft 계정과 로밍할 수도 있습니다.
여러분이 미디어 파일이나 소셜 네트워킹과 같은 보호된 리소스에 액세스하는 서비스를 제공하는 앱을 개발했다고 생각해 봅시다. 서비스 이용을 위해서는 각 사용자의 로그인 정보가 필요합니다. 그래서 여러분은 사용자가 서비스에 로그인할 수 있도록 앱에 사용자 이름과 암호를 입력할 수 있는 UI를 개발할 것이고 특별히 문제는 없습니다.
하지만 여러분은 사용자들에게 좀 더 나은 서비스를 제공하고 싶고 사용자들이 앱을 사용할 때마다 로그인 정보를 입력하지 않아도 되도록 로그인 정보를 안전하게 저장할 수 있기를 원합니다. 그렇다면 바로 자격 증명 보관이 필요합니다. 간단한 자격 증명 보관 API 호출로 사용자 이름과 암호를 저장하고 손쉽게 검색할 수 있으며 사용자가 다음에 앱을 사용할 때 자동으로 로그인할 수 있습니다.
안전한 저장소
자격 증명 보관을 앱에 적용했을 때 가장 좋은 점은 사용자 자격 증명이 안전한 위치에 저장되며 디스크에 저장할 때는 자격 증명 정보가 암호화된다는 점입니다. 물론 여러분의 앱에 대한 사용자 자격 증명을 로컬 저장소에 있는 파일에 저장할 수도 있습니다. 하지만 사용자 자격 증명을 일반 텍스트로 저장하면 보안에 상당한 위험이 생길 수 있습니다. 어떤 사용자의 시스템이 침해되면 그 사용자의 사용자 이름과 암호가 쉽게 액세스되고 도용당할 수 있습니다. 하지만 사용자 이름과 암호를 자격 증명 보관을 이용해 저장하면 악성 소스가 침투하기 쉬운 파일은 암호화됩니다.
자격 증명 보관은 각각의 Windows PC 사용자에게만 고유하게 적용되며 자격 증명에 액세스하는 것은 자격 증명을 저장한 앱에서만 가능합니다. 즉 여러분은 여러분의 앱에 저장한 자격 증명만 검색할 수 있으며, 마찬가지로 다른 앱에서는 여러분의 앱 보관소에 저장된 자격 증명에 접근할 수 없습니다.
자격 증명 로밍
사용자를 위한 새로운 혜택으로, 여러분이 자격 증명 보관을 이용하여 사용자 이름과 암호를 저장하면 사용자는 신뢰할 수 있는 컴퓨터 어디에서나 저장된 자격 증명을 Microsoft 계정과 로밍할 수 있습니다. 이 기능을 이용하면 앱의 보안을 유지하면서도 사용자들이 앱을 더 편리하게 이용할 수 있습니다. 앱이 설치되어 있고 Microsoft 계정이 연결되어 있다면 자격 증명을 다시 확인하지 않아도 신뢰할 수 있는 모든 컴퓨터에서 자동으로 앱에 로그인할 수 있기 때문입니다.
하지만 도메인 계정에서는 조금 다르게 작동합니다. Microsoft 계정으로 자격 증명이 저장된 경우, 이 계정이 도메인 계정(예를 들면, 직장에서 사용하는 계정)과 연결되어 있다면 자격 증명은 그 도메인 계정과 로밍될 수 있습니다. 하지만 도메인 계정에 로그인했을 때 새로 추가된 자격 증명이 있으면 로밍되지 않습니다. 도메인의 개인 자격 증명이 도메인 외부에 노출되는 것을 방지하기 위한 것입니다.
사용자 자격 증명 저장
사용자 자격 증명을 자격 증명 보관으로 저장하는 것은 두 단계로 아주 간단합니다. 먼저 Windows.Security.Credentials 네임스페이스에서 PasswordVault 개체를 사용하여 자격 증명 보관에 대한 참조를 가져옵니다. 그리고 앱의 식별자, 사용자 이름 및 암호를 포함하는 PasswordCredential 개체를 만들어, 이 개체를 자격 증명을 보관소에 추가하기 위한 PasswordVault.Add() 메서드로 보냅니다.
C#
var vault = new Windows.Security.Credentials.PasswordVault(); vault.Add(new Windows.Security.Credentials.PasswordCredential( "My App", username, password));
JavaScript
var vault = new Windows.Security.Credentials.PasswordVault(); vault.add(new Windows.Security.Credentials.PasswordCredential( "My App", username, password));
사용자 자격 증명 검색
PasswordVault 개체에 대한 참조를 가져온 후에는 다음과 같은 몇 가지 방법으로 자격 증명 보관에서 자격 증명을 검색할 수 있습니다.
- 사용자가 보관소의 앱에 제공한 모든 자격 증명을 PasswordVault.RetrieveAll() 메서드를 이용하여 검색할 수 있습니다.
- 저장된 자격 증명의 사용자 이름을 알고 있다면 PasswordVault.FindAllByUserName() 메서드를 이용하여 그 사용자 이름에 대한 모든 자격 증명을 검색할 수 있습니다.
- 저장된 자격 증명의 리소스 이름을 알고 있다면 PasswordVault.FindAllByUserName() 메서드를 이용하여 그 리소스 이름에 대한 모든 자격 증명을 검색할 수 있습니다.
- 마지막으로 자격 증명의 사용자 이름과 리소스 이름을 모두 알고 있다면 PasswordVault.Retrieve() 메서드를 이용하여 바로 그 자격 증명을 검색할 수 있습니다.
리소스 이름을 전체적으로 저장해 놓은 앱에서 사용자의 자격 증명을 찾았을 때 자동으로 사용자가 로그인할 수 있는 예시를 살펴보겠습니다. 한 사용자당 여러 개의 자격 증명이 있을 경우 우리는 사용자에게 로그인 시 기본으로 사용할 자격 증명을 선택하도록 요청하고 있습니다.
C#
private string resourceName = "My App"; private string defaultUserName; private void Login() { var loginCredential = GetCredentialFromLocker(); if (loginCredential != null) { // There is a credential stored in the locker. // Populate the Password property of the credential // for automatic login. loginCredential.RetrievePassword(); } else { // There is no credential stored in the locker. // Display UI to get user credentials. loginCredential = GetLoginCredentialUI(); } // Log the user in. ServerLogin(loginCredential.UserName, loginCredential.Password); } private Windows.Security.Credentials.PasswordCredential GetCredentialFromLocker() { Windows.Security.Credentials.PasswordCredential credential = null; var vault = new Windows.Security.Credentials.PasswordVault(); var credentialList = vault.FindAllByResource(resourceName); if (credentialList.Count > 0) { if (credentialList.Count == 1) { credential = credentialList[0]; } else { // When there are multiple usernames, // retrieve the default username. If one doesn’t // exist, then display UI to have the user select // a default username. defaultUserName = GetDefaultUserNameUI(); credential = vault.Retrieve(resourceName, defaultUserName); } } return credential; }
JavaScript
var resourceName = "My App"; var defaultUserName; function login() { var loginCredential = getCredentialFromLocker(); if (loginCredential != null) { // There is a credential stored in the locker. // Populate the Password property of the credential // for automatic login. loginCredential.retrievePassword(); } else { // There is no credential stored in the locker. // Display UI to get user credentials. loginCredential = getLoginCredentialUI(); } // Log the user in. serverLogin(loginCredential.userName, loginCredential.password); } function GetCredentialFromLocker() { var credential = null; var vault = new Windows.Security.Credentials.PasswordVault(); var credentialList = vault.findAllByResource(resourceName); if (credentialList.length > 0) { if (credentialList.length == 1) { credential = credentialList[0]; } else { // When there are multiple usernames, // retrieve the default username. If one doesn’t // exist, display UI to have the user select // a default username. defaultUserName = getDefaultUserNameUI(); credential = vault.retrieve(resourceName, defaultUserName); } } return credential; }
사용자 자격 증명 삭제
사용자 자격 증명을 자격 증명 보관에서 삭제하는 것 역시 두 단계로 아주 간단합니다. 마찬가지로 Windows.Security.Credentials 네임스페이스에서 PasswordVault 개체를 사용하여 자격 증명 보관에 대한 참조를 가져옵니다. 그리고 삭제하려는 자격 증명을 PasswordVault.Remove() 메서드로 보냅니다.
C#
var vault = new Windows.Security.Credentials.PasswordVault(); vault.Remove(new Windows.Security.Credentials.PasswordCredential( "My App", username, password));
JavaScript
var vault = new Windows.Security.Credentials.PasswordVault(); vault.remove(new Windows.Security.Credentials.PasswordCredential( "My App", username, password));
간편하고 안전함
앞서 살펴보았듯이 자격 증명 보관은 사용자 인증 작업은 물론, 이후에도 지속적으로 편리하게 로그인할 수 있도록 사용자 자격 증명을 저장하는 작업까지 간단하게 할 수 있는 손쉬운 기능입니다. 그리고 이 모든 과정이 아주 안전한 방식으로 이루어집니다.
Windows 8 앱 인증과 관련한 다른 주제로, OAuth와 같은 웹 사이트에서 인증 토큰을 검색하고 사용자의 Microsoft 계정을 기반으로 앱을 개인 설정할 수 있는 웹 인증 브로커도 있습니다.
기타 자세한 내용은 다음을 참조하십시오.
- 사용자 정보 관리(JavaScript)
- 사용자 정보 관리(C#/VB/C++ 및 XAML을 사용한 Windows 스토어 앱)
- 자격 증명 보관 샘플
- Windows.Security.Credentials
- Windows 개발자 콘텐츠, 수석 콘텐츠 개발자, Doug Rothaus
이 블로그 글을 작성하는 데 도움을 준 Yashar Bahman에게 특별히 감사드립니다.