보안: Web API에서 SSL 사용하기
- 본 번역문서의 원문은 Security: Working with SSL in Web API www.asp.net 입니다.
몇 가지 보편적인 인증 스킴들은 평문 HTTP 상에서는 안전하지 않으며, 특히 기본 인증과 폼 인증은 암호화되지 않은 자격 증명을 전송하기 때문에 더욱 그러합니다. 따라서, 안전을 보장하려면 이런 인증 스킴들은 반드시 SSL과 함께 사용해야 합니다. 또한, SSL 클라이언트 인증서를 클라이언트 인증에 사용할 수도 있습니다.
서버에서 SSL 활성화하기
IIS 7이나 그 이상에서 SSL을 설정하려면:
- 인증서를 생성하거나 발급받습니다. 테스트 용도로 자체-서명 인증서(Self-Signed Certificate)를 생성할 수도 있습니다.
- HTTPS 바인딩을 추가합니다.
이에 대한 보다 자세한 내용은 How to Set Up SSL on IIS 7 문서를 참고하시기 바랍니다.
로컬 테스트를 위해서 Visual Studio에서 IIS 익스프레스의 SSL을 활성화시킬 수도 있습니다. 그러려면, 프로젝트의 속성(Properties) 창에서 SSL 사용(SSL Enabled) 항목의 값을 True로 설정합니다. * 그리고, 다음 이미지의 SSL URL 항목의 값에 주의하시기 바랍니다. HTTPS 연결 테스트를 수행하려면 이런 URL을 사용해야 합니다. **
* 프로젝트의 속성 창을 열려면 솔루션 탐색기에서 프로젝트 노드를 클릭한 다음, F4 키를 누릅니다
** 기본적으로 IIS 익스프레스는 44300번 부터 44399번 사이의 포트를 통해서 SSL을 사용할 수 있도록 구성됩니다. 더 자세한 내용은 IIS 익스프레스 FAQ 문서의 "Q: IIS 익스프레스는 SSL을 지원합니까?" 질문을 참고하시기 바랍니다.
Web API 컨트롤러에서 SSL을 강제하기
만약, HTTPS 바인딩과 HTTP 바인딩이 모두 구성되어 있다면 클라이언트는 계속해서 HTTP로도 사이트에 접근할 수 있습니다. 이런 상황에서 일부 리소스들은 HTTP를 통한 접근을 허용하는 반면, 그 외의 리소스들은 SSL을 통해서만 접근할 수 있도록 구성하고 싶을 수도 있습니다. 그런 경우에, 액션 필터를 사용해서 보호하고자 하는 리소스들에 SSL을 통해서만 접근할 수 있도록 강제할 수 있습니다. 다음 코드는 SSL 접근 여부를 확인하는 Web API 인증 필터를 보여줍니다:
public class RequireHttpsAttribute : AuthorizationFilterAttribute { public override void OnAuthorization(HttpActionContext actionContext) { if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps) { actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden) { ReasonPhrase = "HTTPS Required" }; } else { base.OnAuthorization(actionContext); } } }
이 필터를 SSL을 강제하고자 하는 Web API 액션에 추가하면 됩니다:
public class ValuesController : ApiController { [RequireHttps] public HttpResponseMessage Get() { ... } }
SSL 클라이언트 인증서
SSL은 공개 키 기반구조 인증서를 이용한 인증을 제공해줍니다. 이 방식에서 서버는 서버를 인증하는 인증서를 클라이언트에게 제공해야 합니다. 클라이언트 쪽에서 서버에 인증서를 제공하는 경우는 드물지만, 이 방법 역시 클라이언트를 인증할 수 있는 방법 중 한 가지입니다. SSL과 함께 클라이언트 인증서를 사용하려면 서명된 인증서를 사용자들에게 배포할 수 있는 방안이 필요합니다. 대부분의 응용 프로그램 형태에서 이는 그다지 좋은 사용자 경험을 제공해주지는 못하지만, 일부 환경에는(기업 내부 환경 등) 적합할 수도 있습니다.
장점 | 단점 |
---|---|
|
|
IIS가 클라이언트 인증서를 받아들이도록 구성하려면, IIS 관리자에서 다음의 과정들을 수행합니다:
- 트리 뷰에서 설정하고자 하는 사이트의 노드를 클릭합니다.
- 메인 패인에서 SSL 설정(SSL Settings) 기능을 더블 클릭합니다.
- 클라이언트 인증서(Client Certificates) 항목에서 다음 중 한 가지 옵션을 선택합니다:
- 수락(Accept): 클라이언트가 인증서를 제공하는 경우, IIS에서 이를 받아들이지만 필수로 요구하지는 않습니다.
- 필요(Require): 클라이언트 인증서를 필수로 요구합니다. (이 옵션을 활성화시키려면 SSL 필요(Require SSL) 항목도 체크해야 합니다.)
역주: 사이트에 HTTPS 바인딩을 추가해야만 SSL 설정(SSL Settings) 기능 내의 항목들이 활성화됩니다.
또는, ApplicationHost.config 파일을 직접 편집해서 이 옵션들을 설정할 수도 있습니다:
<system.webServer> <security> <access sslFlags="Ssl, SslNegotiateCert" /> <!-- To require a client cert: --> <!-- <access sslFlags="Ssl, SslRequireCert" /> --> </security> </system.webServer>
이 설정에서 SslNegotiateCert 플래그는 IIS가 클라이언트로부터 인증서를 받아들이지만, 필수로 요구하지는 않도록 지정합니다 (IIS 관리자의 수락(Accept) 옵션과 동일합니다). 반면, 인증서를 필수로 요구하려면 SslRequireCert 플래그를 설정합니다. 로컬 테스트를 위해서 이 옵션들을 "Documents\IISExpress\config"에 위치한 로컬 applicationhost.Config 파일에 설정해서 IIS 익스프레스에 적용할 수도 있습니다. (역주: 파일 탐색기의 경로 창에 %USERPROFILE%\Documents\IISExpress\config를 입력합니다.)
테스트 용 클라이언트 인증서 생성하기
직접 MakeCert.exe를 사용해서 테스트 용 클라이언트 인증서를 생성할 수 있습니다. 먼저, 테스트 루트 인증기관을 생성합니다:
makecert.exe -n "CN=Development CA" -r -sv TempCA.pvk TempCA.cer
이 명령을 수행하면 MakeCert 프로그램이 개인 키의 비밀번호를 입력하도록 프롬프트를 출력합니다.
그런 다음, 다음과 같이 인증서를 테스트 서버의 신뢰할 수 있는 루트 인증 기관(Trusted Root Certification Authorities) 저장소에 추가합니다:
- MMC를 실행합니다.
- 파일(File) 메뉴에서 스냅인 추가/제거(Add/Remove Snap-In)를 선택합니다.
- 인증서(Certificate) 스냅인을 선택해서 추가하고, 마법사에서 컴퓨터 계정(Computer Account) 옵션을 선택합니다.
- 로컬 컴퓨터(Local computer) 옵션을 선택한 다음 마법사를 완료합니다.
- 좌측 트리 뷰에서 신뢰할 수 있는 루트 인증 기관(Trusted Root Certification Authorities) 노드를 선택 및 확장합니다.
- 동작(Action) 메뉴에서 모든 작업(All Tasks)을 선택한 다음, 가져오기(Import)를 클릭해서 인증서 가져오기 마법사(Certificate Import Wizard)를 시작합니다.
- 방금 생성한 TempCA.cer 인증서 파일을 찾아서 선택합니다.
- 지시에 따라 마법사를 완료합니다.
역주: 이 과정을 원문의 지시대로 따라해보면 실제 상황과 맞지 않는 경우를 접하게 됩니다. 원문의 내용이 다소 부실한 편이어서 본 번역문에서는 일부 내용을 조정했습니다. 다만, 전체적인 맥락을 파악하는 데에는 무리가 없으므로 참고하시기 바랍니다.
이제 첫 번째 인증서로 서명된 클라이언트 인증서를 생성합니다:
makecert.exe -pe -ss My -sr CurrentUser -a sha1 -sky exchange -n "CN=name" -eku 1.3.6.1.5.5.7.3.2 -sk SignedByCA -ic TempCA.cer -iv TempCA.pvk
Web API에서 클라이언트 인증서 사용하기
서버 측에서는 요청 메시지에 대해 GetClientCertificate 메서드를 호출해서 클라이언트 인증서를 얻을 수 있습니다. 이 메서드는 클라이언트 인증서가 존재하지 않으면 null을 반환합니다. 반면, 클라이언트 인증서가 존재하면 X509Certificate2 인스턴스를 반환합니다. 이 개체를 이용해서 발급자나 주체 같은 인증서 정보를 알아낼 수 있습니다. 그런 다음, 이 정보들을 이용해서 인증을 수행하거나 권한을 부여하면 됩니다.
X509Certificate2 cert = Request.GetClientCertificate(); string issuer = cert.Issuer; string subject = cert.Subject;
- 여러분의 첫 번째 ASP.NET Web API (C#) 2013-05-27 20:30
- CRUD 작업을 지원하는 Web API 작성하기 2013-06-14 20:30
- ASP.NET 웹폼에서 Web API 사용하기 2013-06-25 20:30
- ASP.NET Web API와 라우팅 2013-07-10 20:30
- ASP.NET Web API 도움말 페이지 작성하기 2013-08-14 15:43
- .NET 클라이언트에서 Web API 호출하기 (C#) 2013-08-21 16:26
- WPF 응용 프로그램에서 Web API 호출하기 (C#) 2013-08-28 22:41
- HttpClient 메시지 처리기 2013-09-04 17:16
- ASP.NET Web API 예외 처리 2013-09-11 21:23
- HTML 폼 데이터 전송하기 - 파트 1 2013-09-18 21:23
- HTML 폼 데이터 전송하기 - 파트 2 2013-09-25 01:11
- ASP.NET Web API와 HTTP 쿠키 2013-10-02 09:00
- 자체-호스트(Self-Host) Web API (C#) 2013-10-09 15:59
- OWIN을 이용한 ASP.NET Web API 자체 호스트(Self-Host) 2014-01-17 08:00
- 보안: ASP.NET Web API의 인증(Authentication)과 권한(Authorization) 2014-01-20 08:00
- 보안: 기본 인증 2014-01-22 08:00
- 보안: ASP.NET Web API와 개별 사용자 계정 2014-01-24 08:00
- 보안: 폼 인증 2014-01-27 08:00
- 보안: 통합 Windows 인증 2014-01-29 08:00
- 보안: 크로스 사이트 요청 위조(Cross-Site Request Forgery) 공격 방지하기 2014-02-03 08:00
- 보안: Web API에서 SSL 사용하기 2014-02-05 08:00
- 보안: 외부 인증 서비스 (C#) 2014-02-07 08:00
- 보안: ASP.NET Web API 교차-원본 요청(Cross-Origin Request) 활성화하기 2014-02-10 08:00