작성자: 릭 앤더슨
이 자습서에서는 Two-Factor 인증을 사용하여 ASP.NET MVC 5 웹앱을 빌드하는 방법을 보여줍니다. 계속하기 전에 로그인, 전자 메일 확인 및 암호 재설정 사용하여 보안 ASP.NET MVC 5 웹앱 만들기
완료해야 합니다. 여기에서 완료된 애플리케이션다운로드할 수 있습니다. 다운로드에는 전자 메일 또는 SMS 공급자를 설정하지 않고 전자 메일 확인 및 SMS를 테스트할 수 있는 디버깅 도우미가 포함되어 있습니다. 이 자습서는 릭 앤더슨 (트위터: @RickAndMSFT)에 의해 작성되었습니다.
ASP.NET MVC 앱 만들기
먼저 Visual Studio Express 2013 for Web 이상을 설치한 후 실행합니다.
메모
경고: 계속하기 전에 로그인, 전자 메일 확인 및 암호 재설정 있는 보안 ASP.NET MVC 5 웹앱 만들기
- 새 ASP.NET 웹 프로젝트를 만들고 MVC 템플릿을 선택합니다. Web Forms는 ASP.NET ID도 지원하므로 웹 양식 앱에서 유사한 단계를 수행할 수 있습니다.
새 ASP.NET 프로젝트 창을 보여 주는 - 기본 인증은 개별 사용자 계정
그대로 둡니다. Azure에서 앱을 호스트하려면 확인란을 선택한 상태로 둡니다. 자습서의 뒷부분에서 Azure에 배포합니다. Azure 계정을 무료로열 수 있습니다. - SSL사용하도록
프로젝트를 설정합니다.
2단계 인증을 위한 SMS 설정
이 자습서에서는 Twilio 또는 ASPSMS를 사용하기 위한 지침을 제공하지만 다른 SMS 공급자를 사용할 수 있습니다.
SMS 공급자를 사용하여 사용자 계정 만들기
추가 패키지 설치 또는 서비스 참조 추가
Twilio:
패키지 관리자 콘솔에서 다음 명령을 입력합니다.
Install-Package Twilio
ASPSMS:
다음 서비스 참조를 추가해야 합니다.서비스 참조 추가 창을 보여 주는
주소:
https://webservice.aspsms.com/aspsmsx2.asmx?WSDL
Namespace:
ASPSMSX2
SMS 공급자 사용자 자격 증명 알아내기
가장 안전한 인증 옵션을 사용하는 것이 좋습니다. Azure에 배포된 .NET 앱은 다음을 참조하세요.
- .NET용 Azure Key Vault 라이브러리
- .NET Aspire와 Azure Key Vault 통합
Azure Key Vault 및 .NET Aspire 비밀을 저장하고 검색하는 가장 안전한 방법을 제공합니다. Azure Key Vault는 인증서, 연결 문자열 및 암호와 같은 암호화 키와 비밀을 보호하는 클라우드 서비스입니다. .NET Aspire의 경우 호스팅과 클라이언트 통합간의
리소스 소유자 암호 자격 증명 부여를 사용하지 마세요. 그 이유는 다음과 같습니다.
- 클라이언트에 사용자의 암호를 노출합니다.
- 중요한 보안 위험입니다.
- 다른 인증 흐름을 사용할 수 없는 경우에만 사용해야 합니다.
앱이 테스트 서버에 배포되면 환경 변수를 사용하여 연결 문자열을 테스트 데이터베이스 서버로 설정할 수 있습니다. 환경 변수는 일반적으로 암호화되지 않은 일반 텍스트로 저장됩니다. 컴퓨터 또는 프로세스가 손상된 경우 신뢰할 수 없는 당사자가 환경 변수에 액세스할 수 있습니다. 환경 변수를 사용하여 프로덕션 연결 문자열을 저장하는 것은 추천하지 않습니다. 이는 가장 안전한 방법이 아니기 때문입니다.
구성 데이터 지침:
- 암호 또는 기타 중요한 데이터를 구성 공급자 코드 또는 일반 텍스트 구성 파일에 저장하지 마세요.
- 개발 또는 테스트 환경에서 프로덕션 비밀을 사용하지 마세요.
- 소스 코드 리포지토리에 실수로 커밋할 수 없도록 프로젝트 외부에서 비밀을 지정합니다.
Twilio:
Twilio 계정의 대시보드 탭에서 계정 SID와 인증 토큰를 복사하세요.
ASPSMS:
계정 설정에서 Userkey으로 이동하여, 사용자가 설정한 비밀번호와 함께 복사하십시오.
나중에 이러한 값을 키 및 "SMSAccountIdentification"
내의 "SMSAccountPassword"
파일에 저장합니다.
4. SenderID/Originator 지정
Twilio:
번호 탭에서 Twilio 전화번호를 복사하세요.
ASPSMS:
메뉴의 잠금 해제, 하나 이상의 발신기 잠금 해제 또는 영숫자 원본(모든 네트워크에서 지원되지 않음)을 선택합니다.
나중에 이 값을 키 내의 "SMSAccountFrom"
파일에 저장합니다.
5. SMS 공급자 자격 증명을 앱으로 전송
앱에서 자격 증명과 발신자 전화번호에 접근할 수 있도록 합니다. 작업을 간단하게 유지하기 위해 이러한 값을 web.config 파일에 저장합니다. Azure에 배포할 때 웹 사이트 구성 탭의 앱 설정 섹션에 값을 안전하게 저장할 수 있습니다.
[!code-xml[Main](aspnet-mvc-5-app-with-sms-and-email-two-factor-authentication/samples/sample1.xml?highlight=8-10)]
> [!WARNING]
> Security - Never store sensitive data in your source code. The account and credentials are added to the code above to keep the sample simple. See [Best practices for deploying passwords and other sensitive data to ASP.NET and Azure](../../../identity/overview/features-api/best-practices-for-deploying-passwords-and-other-sensitive-data-to-aspnet-and-azure.md).
SMS 공급자 데이터 전송 구현
SmsService
파일에서 클래스를 구성합니다.사용된 SMS 공급자에 따라 Twilio 또는 ASPSMS 섹션을 활성화합니다.
public class SmsService : IIdentityMessageService { public Task SendAsync(IdentityMessage message) { // Twilio Begin //var accountSid = ConfigurationManager.AppSettings["SMSAccountIdentification"]; //var authToken = ConfigurationManager.AppSettings["SMSAccountPassword"]; //var fromNumber = ConfigurationManager.AppSettings["SMSAccountFrom"]; //TwilioClient.Init(accountSid, authToken); //MessageResource result = MessageResource.Create( //new PhoneNumber(message.Destination), //from: new PhoneNumber(fromNumber), //body: message.Body //); ////Status is one of Queued, Sending, Sent, Failed or null if the number is not valid //Trace.TraceInformation(result.Status.ToString()); ////Twilio doesn't currently have an async API, so return success. //return Task.FromResult(0); // Twilio End // ASPSMS Begin // var soapSms = new MvcPWx.ASPSMSX2.ASPSMSX2SoapClient("ASPSMSX2Soap"); // soapSms.SendSimpleTextSMS( // System.Configuration.ConfigurationManager.AppSettings["SMSAccountIdentification"], // System.Configuration.ConfigurationManager.AppSettings["SMSAccountPassword"], // message.Destination, // System.Configuration.ConfigurationManager.AppSettings["SMSAccountFrom"], // message.Body); // soapSms.Close(); // return Task.FromResult(0); // ASPSMS End } }
Views\Manage\Index.cshtml Razor 보기를 업데이트합니다. (참고: 종료 코드에서 주석을 제거하지 말고 아래 코드를 사용하세요.)
@model MvcPWy.Models.IndexViewModel @{ ViewBag.Title = "Manage"; } <h2>@ViewBag.Title.</h2> <p class="text-success">@ViewBag.StatusMessage</p> <div> <h4>Change your account settings</h4> <hr /> <dl class="dl-horizontal"> <dt>Password:</dt> <dd> [ @if (Model.HasPassword) { @Html.ActionLink("Change your password", "ChangePassword") } else { @Html.ActionLink("Create", "SetPassword") } ] </dd> <dt>External Logins:</dt> <dd> @Model.Logins.Count [ @Html.ActionLink("Manage", "ManageLogins") ] </dd> <dt>Phone Number:</dt> <dd> @(Model.PhoneNumber ?? "None") [ @if (Model.PhoneNumber != null) { @Html.ActionLink("Change", "AddPhoneNumber") @: | @Html.ActionLink("Remove", "RemovePhoneNumber") } else { @Html.ActionLink("Add", "AddPhoneNumber") } ] </dd> <dt>Two-Factor Authentication:</dt> <dd> @if (Model.TwoFactor) { using (Html.BeginForm("DisableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <text>Enabled <input type="submit" value="Disable" class="btn btn-link" /> </text> } } else { using (Html.BeginForm("EnableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { @Html.AntiForgeryToken() <text>Disabled <input type="submit" value="Enable" class="btn btn-link" /> </text> } } </dd> </dl> </div>
EnableTwoFactorAuthentication
특성이DisableTwoFactorAuthentication
의ManageController
및 작업 메서드에 있는지 확인합니다.// // POST: /Manage/EnableTwoFactorAuthentication [HttpPost,ValidateAntiForgeryToken] public async Task<ActionResult> EnableTwoFactorAuthentication() { await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true); var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); if (user != null) { await SignInAsync(user, isPersistent: false); } return RedirectToAction("Index", "Manage"); } // // POST: /Manage/DisableTwoFactorAuthentication [HttpPost, ValidateAntiForgeryToken] public async Task<ActionResult> DisableTwoFactorAuthentication() { await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false); var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); if (user != null) { await SignInAsync(user, isPersistent: false); } return RedirectToAction("Index", "Manage"); }
앱을 실행하고 이전에 등록한 계정으로 로그인합니다.
사용자 ID를 클릭하면
Index
컨트롤러에서Manage
작업 메서드가 활성화됩니다.
A SP dot NET 앱 홈 페이지를 보여 주는추가를 클릭합니다.
A S P 점 NET 앱의 계정 설정 페이지를 보여주는AddPhoneNumber
작업 메서드는 SMS 메시지를 받을 수 있는 전화 번호를 입력하는 대화 상자를 표시합니다.// GET: /Account/AddPhoneNumber public ActionResult AddPhoneNumber() { return View(); }
몇 초 후에 확인 코드가 포함된 문자 메시지가 표시됩니다. 입력하고 제출누르세요.
관리 보기는 전화 번호가 추가되었음을 보여 줍니다.
2단계 인증 사용
템플릿 생성 앱에서 UI를 사용하여 2FA(2단계 인증)를 사용하도록 설정해야 합니다. 2FA를 사용하도록 설정하려면 탐색 모음에서 사용자 ID(전자 메일 별칭)를 클릭합니다.
2FA 활성화를 클릭합니다.
ASP.NET 앱 계정 설정 페이지를 보여주는
로그아웃한 다음 다시 로그인합니다. 전자 메일을 사용하도록 설정한 경우(이전 자습서
A SP dot NET 앱 송신 확인 코드 페이지를 보여 주는
코드 확인 페이지는 SMS 또는 전자 메일에서 코드를 입력할 수 있는 위치에 표시됩니다.
'이 브라우저 기억하기' 확인란을 클릭하면 해당 브라우저와 디바이스에서 2단계 인증(2FA)을 사용하지 않고도 로그인할 수 있습니다. 악의적인 사용자가 기기에 액세스할 수 없는 한, 2FA를 활성화하고 이 브라우저 기억하기 버튼을 클릭하면 신뢰할 수 없는 기기로부터의 모든 접근에 대해 강력한 2FA 보호를 유지하면서도, 편리하게 한 단계로 암호에 접근할 수 있습니다. 정기적으로 사용하는 모든 개인 디바이스에서 이 작업을 수행할 수 있습니다.
이 자습서에서는 새 ASP.NET MVC 앱에서 2FA를 사용하도록 설정하는 방법을 간략하게 소개합니다. 내 자습서 "SMS 및 이메일을 사용한 2단계 인증과 ASP.NET Identity"은 샘플의 코드를 자세히 설명합니다.
추가 리소스
- ASP.NET Identity를 사용하여 SMS 및 전자 메일로 2단계 인증 2단계 인증에 대해 자세히 설명합니다.
- ASP.NET ID 권장 리소스 대한
링크 - ASP.NET Identity로 계정 확인 및 암호 복구 계정 확인과 암호 복구에 대해 더 자세히 설명합니다.
- Facebook, Twitter, LinkedIn 및 Google OAuth2 로그온 MVC 5 앱
이 자습서에서는 Facebook, Twitter, LinkedIn 및 Google의 OAuth 2.0 인증을 사용하여 ASP.NET MVC 5 앱을 작성하는 방법을 보여줍니다. 또한 ID 데이터베이스에 추가 데이터를 추가하는 방법도 보여줍니다. - 멤버 자격, OAuth 및 SQL Database를 사용하여 보안 ASP.NET MVC 앱을 Azure Web배포합니다. 이 자습서에서는 Azure 배포, 역할로 앱을 보호하는 방법, 멤버 자격 API를 사용하여 사용자 및 역할을 추가하는 방법 및 추가 보안 기능을 추가합니다.
- OAuth 2용 Google 앱을 만들고 앱을 프로젝트에 연결하기
- Facebook에서 앱을 만들고 프로젝트에 앱 연결
- 프로젝트에서 SSL 설정하기
- C# 및 ASP.NET MVC 개발 환경을 설정하는 방법