Facebook, Twitter, LinkedIn 및 Google OAuth2 로그온을 제공하는 ASP.NET MVC 5 앱 만들기(C#)

작성자 : Rick Anderson

이 자습서에서는 사용자가 Facebook, Twitter, LinkedIn, Microsoft 또는 Google과 같은 외부 인증 공급자의 자격 증명으로 OAuth 2.0 을 사용하여 로그인할 수 있도록 하는 ASP.NET MVC 5 웹 애플리케이션을 빌드하는 방법을 보여 줍니다. 간단히 하기 위해 이 자습서에서는 Facebook 및 Google의 자격 증명 작업에 중점을 둡니다.

수백만 명의 사용자가 이미 이러한 외부 공급자와 계정을 가지고 있기 때문에 웹 사이트에서 이러한 자격 증명을 사용하도록 설정하면 상당한 이점이 있습니다. 이러한 사용자는 새 자격 증명 집합을 만들고 기억할 필요가 없는 경우 사이트에 등록하는 경향이 더 높아질 수 있습니다.

SMS 및 이메일 Two-Factor 인증을 사용하여 MVC 5 앱 ASP.NET 참조하세요.

또한 이 자습서에서는 사용자에 대한 프로필 데이터를 추가하는 방법과 멤버 자격 API를 사용하여 역할을 추가하는 방법을 보여 줍니다. 이 자습서는 Rick Anderson 이 작성했습니다( Twitter에서 나를 따르세요: @RickAndMSFT ).

시작하기

먼저 웹 또는Visual Studio 2013 Visual Studio Express 2013을 설치하고 실행합니다. Visual Studio 2013 업데이트 3 이상을 설치합니다.

참고

Google OAuth 2를 사용하고 SSL 경고 없이 로컬로 디버그하려면 Visual Studio 2013 업데이트 3 이상을 설치해야 합니다.

시작 페이지에서 새 프로젝트를 클릭하거나 메뉴를 사용하여 파일을 선택한 다음 새 프로젝트를 선택할 수 있습니다.

Visual Studio 시작 페이지를 보여 주는 스크린샷

첫 번째 애플리케이션 만들기

새 프로젝트를 클릭한 다음 왼쪽에서 Visual C#을 선택한 다음, 웹을 선택한 다음 ASP.NET 웹 애플리케이션을 선택합니다. 프로젝트 이름을 "MvcAuth"로 지정한 다음 확인을 클릭합니다.

Visual Studio 새 프로젝트 메뉴 페이지를 보여 주는 스크린샷 이름 텍스트 필드에 M v c 인증을 입력합니다.

새 ASP.NET 프로젝트 대화 상자에서 MVC를 클릭합니다. 인증이 개별 사용자 계정이 아닌 경우 인증 변경 단추를 클릭하고 개별 사용자 계정을 선택합니다. 클라우드에서 호스트를 확인하면 앱이 Azure에서 호스트하기가 매우 쉽습니다.

새 ASP 점 NET 프로젝트 대화 상자를 보여 주는 스크린샷. 인증 변경 단추 및 클라우드의 호스트 확인란이 강조 표시되어 있습니다.

클라우드에서 호스트를 선택한 경우 구성 대화 상자를 완료합니다.

Microsoft Azure 웹 사이트 구성 대화 상자를 보여 주는 스크린샷. 샘플 데이터베이스 암호가 입력됩니다.

NuGet을 사용하여 최신 OWIN 미들웨어로 업데이트

NuGet 패키지 관리자를 사용하여 OWIN 미들웨어를 업데이트합니다. 왼쪽 메뉴에서 업데이트 선택합니다. 모두 업데이트 단추를 클릭하거나 OWIN 패키지만 검색할 수 있습니다(다음 이미지에 표시됨).

Nu GET 패키지 관리 대화 상자를 보여 주는 스크린샷 업데이트 표시줄과 모두 업데이트 단추가 강조 표시됩니다.

아래 이미지에는 OWIN 패키지만 표시됩니다.

Nu GET 패키지 관리 대화 상자를 보여 주는 스크린샷 업데이트 표시줄과 OWN이 입력된 검색 창이 강조 표시됩니다.

PMC(패키지 관리자 콘솔)에서 모든 패키지를 업데이트하는 명령을 입력 Update-Package 할 수 있습니다.

F5 또는 Ctrl+F5를 눌러 애플리케이션을 실행합니다. 아래 이미지에서 포트 번호는 1234입니다. 애플리케이션을 실행하면 다른 포트 번호가 표시됩니다.

브라우저 창의 크기에 따라 탐색 아이콘을 클릭하여 , 정보, 연락처, 등록로그인 링크를 확인해야 할 수 있습니다.

내 ASP 점 NET 홈페이지를 보여 주는 스크린샷. 탐색 아이콘이 강조 표시됩니다.
내 ASP 점 NET 홈페이지를 보여 주는 스크린샷. 탐색 아이콘이 강조 표시되고 선택되어 탐색 링크가 있는 드롭다운 메뉴가 표시됩니다.

프로젝트에서 SSL 설정

Google 및 Facebook과 같은 인증 공급자에 연결하려면 SSL을 사용하도록 IIS-Express 설정해야 합니다. 로그인 후 SSL을 계속 사용하고 HTTP로 다시 삭제하지 않는 것이 중요하며, 로그인 쿠키는 사용자 이름 및 암호와 마찬가지로 비밀이며 SSL을 사용하지 않으면 유선에서 지우기 텍스트로 전송됩니다. 또한 MVC 파이프라인을 실행하기 전에 핸드셰이크를 수행하고 채널(HTTPS를 HTTP보다 느리게 만드는 대부분의 요소)을 보호하는 데 이미 시간이 걸렸으므로 로그인한 후 HTTP로 다시 리디렉션해도 현재 요청이나 향후 요청이 훨씬 빨라지지 않습니다.

  1. 솔루션 탐색기MvcAuth 프로젝트를 클릭합니다.

  2. F4 키를 눌러 프로젝트 속성을 표시합니다. 또는 보기 메뉴에서 속성 창을 선택할 수 있습니다.

  3. SSL 사용을 True로 변경합니다.

    M v c 인증 프로젝트의 솔루션 탐색기 프로젝트 속성을 보여 주는 스크린샷. SSL Enabled True 및 S L U R L이 강조 표시되어 있습니다.

  4. SSL URL( https://localhost:44300/ 다른 SSL 프로젝트를 만들지 않은 경우)을 복사합니다.

  5. 솔루션 탐색기MvcAuth 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다.

  6. 탭을 선택한 다음, SSL URL을 프로젝트 URL 상자에 붙여넣습니다. 파일을 저장합니다(Ctl+S). Facebook 및 Google 인증 앱을 구성하려면 이 URL이 필요합니다.

    M v c 인증 프로젝트의 속성 페이지를 보여 주는 스크린샷. 왼쪽 메뉴의 웹 탭과 Project U R L 상자에 붙여넣은 SSL URL이 강조 표시됩니다.

  7. 모든 요청이 HTTPS를 사용해야 함을 요구하도록 컨트롤러에 HomeRequireHttps 특성을 추가합니다. 보다 안전한 방법은 RequireHttps 필터를 애플리케이션에 추가하는 것입니다. 내 자습서에서 인증 및 SQL DB를 사용하여 ASP.NET MVC 앱 만들기 및 Azure App Service 배포에서 "SSL 및 권한 부여 특성으로 애플리케이션 보호" 섹션을 참조하세요. 홈 컨트롤러의 일부가 아래에 나와 있습니다.

    [RequireHttps]
    public class HomeController : Controller
    {
       public ActionResult Index()
       {
          return View();
       }
    
  8. Ctrl+F5를 눌러 애플리케이션을 실행합니다. 이전에 인증서를 설치한 경우 이 섹션의 나머지 부분을 건너뛰고 OAuth 2용 Google 앱 만들기로 이동하여 앱을 프로젝트에 연결할 수 있습니다. 그렇지 않으면 지침에 따라 IIS Express 생성한 자체 서명된 인증서를 신뢰합니다.

    I S Express SSL 인증서를 신뢰할지 여부를 선택하라는 Visual Studio 대화 상자를 보여 주는 스크린샷

  9. 보안 경고 대화 상자를 읽은 다음 localhost를 나타내는 인증서를 설치하려면 예를 클릭합니다.

    사용자에게 인증서 설치 여부를 선택하라는 Visual Studio 보안 경고 대화 상자를 보여 주는 스크린샷.

  10. IE에 페이지가 표시되며 SSL 경고가 없습니다.

    SSL 경고가 없는 내 ASP 점 NET 홈 페이지를 보여 주는 스크린샷.

  11. Google Chrome도 인증서를 수락하고 경고 없이 HTTPS 콘텐츠를 표시합니다. Firefox는 자체 인증서 저장소를 사용하므로 경고를 표시합니다. 애플리케이션의 경우 I Understand the Risks(위험 이해)를 안전하게 클릭할 수 있습니다.

    Firefox에서 실행되는 내 ASP 점 NET 앱을 보여 주는 스크린샷. 신뢰할 수 없는 연결 경고 페이지에서 사용자에게 애플리케이션을 수락하고 계속할지 여부를 묻는 메시지가 표시됩니다.

OAuth 2용 Google 앱 만들기 및 프로젝트에 앱 연결

경고

현재 Google OAuth 지침은 ASP.NET Core Google 인증 구성을 참조하세요.

  1. Google Developers Console로 이동합니다.

  2. 이전에 프로젝트를 만들지 않은 경우 왼쪽 탭에서 자격 증명 을 선택한 다음 , 만들기를 선택합니다.

  3. 왼쪽 탭에서 자격 증명을 클릭합니다.

  4. 자격 증명 만들기를 클릭한 다음 OAuth 클라이언트 ID를 클릭합니다.

    1. 클라이언트 ID 만들기 대화 상자에서 애플리케이션 유형에 대한 기본 웹 애플리케이션을 유지합니다.
    2. 권한 있는 JavaScript 원본을 위에서 사용한 SSL URL로 설정합니다(https://localhost:44300/다른 SSL 프로젝트를 만들지 않은 경우).
    3. 권한 있는 리디렉션 URI를 다음으로 설정합니다.
      https://localhost:44300/signin-google
  5. OAuth 동의 화면 메뉴 항목을 클릭한 다음 전자 메일 주소 및 제품 이름을 설정합니다. 양식을 완료하면 저장을 클릭합니다.

  6. 라이브러리 메뉴 항목을 클릭하고 Google+ API를 검색한 다음, 사용을 누릅니다.

    검색 결과 목록을 표시하는 스크린샷 Google 및 AP I 검색 결과가 강조 표시됩니다.

    아래 이미지는 활성화된 API를 보여 줍니다.

    API를 사용하도록 설정된 Google 개발자 콘솔 페이지 목록을 보여 주는 스크린샷. 옆에 녹색 ON 단추가 표시되면 P I가 활성화된 것으로 표시됩니다.

  7. Google API API Manager에서 자격 증명 탭을 방문하여 클라이언트 ID를 가져옵니다. 애플리케이션 비밀을 사용하여 JSON 파일을 저장하려면 다운로드합니다. ClientIdClientSecret을 복사하여 UseGoogleAuthenticationApp_Start 폴더의 Startup.Auth.cs 파일에 있는 메서드에 붙여넣습니다. 아래 표시된 ClientIdClientSecret 값은 샘플이며 작동하지 않습니다.

    public void ConfigureAuth(IAppBuilder app)
    {
        // Configure the db context and user manager to use a single instance per request
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    
        // Enable the application to use a cookie to store information for the signed in user
        // and to use a cookie to temporarily store information about a user logging in with a third party login provider
        // Configure the sign in cookie
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
            }
        });
        
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
        // Uncomment the following lines to enable logging in with third party login providers
        //app.UseMicrosoftAccountAuthentication(
        //    clientId: "",
        //    clientSecret: "");
    
        //app.UseTwitterAuthentication(
        //   consumerKey: "",
        //   consumerSecret: "");
    
        //app.UseFacebookAuthentication(
        //   appId: "",
        //   appSecret: "");
    
        app.UseGoogleAuthentication(
             clientId: "000-000.apps.googleusercontent.com",
             clientSecret: "00000000000");
    }
    

    경고

    보안 - 소스 코드에 중요한 데이터를 저장하지 않습니다. 위의 코드에 계정 및 자격 증명이 추가되어 샘플을 단순하게 유지합니다. 암호 및 기타 중요한 데이터를 ASP.NET 및 Azure App Service 배포하기 위한 모범 사례를 참조하세요.

  8. Ctrl+F5를 눌러 애플리케이션을 빌드하고 실행합니다. 로그인 링크를 클릭합니다.

    내 ASP 점 NET 홈페이지를 보여 주는 스크린샷. 탐색 단추와 로그인 링크가 강조 표시됩니다.

  9. 다른 서비스를 사용하여 로그인에서Google을 클릭합니다.

    내 ASP 점 NET 로그인 페이지를 보여 주는 스크린샷. 다른 서비스를 사용하여 로그인 대화 상자 및 Google 단추가 강조 표시되어 있습니다.

    참고

    위의 단계를 놓치면 HTTP 401 오류가 발생합니다. 위의 단계를 다시 확인합니다. 필요한 설정(예: 제품 이름)을 놓친 경우 누락된 항목을 추가하고 저장합니다. 인증이 작동하는 데 몇 분 정도 걸릴 수 있습니다.

  10. 자격 증명을 입력할 Google 사이트로 리디렉션됩니다.

    Google 계정 로그인 페이지를 보여 주는 스크린샷 샘플 자격 증명은 텍스트 필드에 입력됩니다.

  11. 자격 증명을 입력하면 방금 만든 웹 애플리케이션에 권한을 부여하라는 메시지가 표시됩니다.

    사용자에게 웹 애플리케이션에 대한 오프라인 액세스를 취소하거나 수락하라는 메시지를 표시하는 Google 계정 권한 요청 페이지를 보여 주는 스크린샷.

  12. Accept를 클릭합니다. 이제 Google 계정을 등록할 수 있는 MvcAuth 애플리케이션의 등록 페이지로 다시 리디렉션됩니다. Gmail 계정에 사용되는 로컬 전자 메일 등록 이름을 변경할 수 있지만 일반적으로 기본 전자 메일 별칭(즉, 인증에 사용하는 별칭)을 그대로 사용합니다. 등록을 클릭합니다.

    내 ASP 점 NET 애플리케이션 등록 페이지를 보여 주는 스크린샷. 샘플 Google 계정이 전자 메일 텍스트 필드에 입력됩니다.

Facebook에서 앱 만들기 및 프로젝트에 앱 연결

경고

현재 Facebook OAuth2 인증 지침은 Facebook 인증 구성을 참조하세요.

서버 Explorer 사용하여 멤버 자격 데이터 검사

보기 메뉴에서 서버 Explorer 클릭합니다.

서버 Explorer 강조 표시된 Visual Studio 보기 드롭다운 메뉴를 보여 주는 스크린샷

DefaultConnection(MvcAuth)을 확장하고 테이블을 확장하고 AspNetUsers를 마우스 오른쪽 단추로 클릭한 다음 테이블 데이터 표시를 클릭합니다.

서비스 Explorer 메뉴 옵션을 보여 주는 스크린샷 데이터 연결, 기본 연결 M v c 인증 및 테이블 탭이 확장됩니다.

aspnetusers 테이블 데이터

사용자 클래스에 프로필 데이터 추가

이 섹션에서는 다음 이미지와 같이 등록하는 동안 생년월일 및 홈타운을 사용자 데이터에 추가합니다.

홈 타운과 Bday와 reg

Models\IdentityModels.cs 파일을 열고 생년월일 및 홈타운 속성을 추가합니다.

public class ApplicationUser : IdentityUser
{
    public string HomeTown { get; set; }
    public System.DateTime? BirthDate { get; set; }
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

에서 Models\AccountViewModels.cs 파일 및 설정된 생년월일 및 홈타운 속성을 ExternalLoginConfirmationViewModel엽니다.

public class ExternalLoginConfirmationViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    public string HomeTown { get; set; }
    public System.DateTime? BirthDate { get; set; }
}

Controllers\AccountController.cs 파일을 열고 다음과 같이 작업 메서드에서 생년월일 및 홈타운에 ExternalLoginConfirmation 대한 코드를 추가합니다.

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
    if (User.Identity.IsAuthenticated)
    {
        return RedirectToAction("Manage");
    }

    if (ModelState.IsValid)
    {
        // Get the information about the user from the external login provider
        var info = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (info == null)
        {
            return View("ExternalLoginFailure");
        }
        var user = new ApplicationUser() 
        {
            UserName = model.Email, Email = model.Email,
            BirthDate = model.BirthDate,
            HomeTown  = model.HomeTown
        
        };
        IdentityResult result = await UserManager.CreateAsync(user);
        if (result.Succeeded)
        {
            result = await UserManager.AddLoginAsync(user.Id, info.Login);
            if (result.Succeeded)
            {
                await SignInAsync(user, isPersistent: false);
                
                // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
                // Send an email with this link
                // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                // SendEmail(user.Email, callbackUrl, "Confirm your account", "Please confirm your account by clicking this link");
                
                return RedirectToLocal(returnUrl);
            }
        }
        AddErrors(result);
    }

    ViewBag.ReturnUrl = returnUrl;
    return View(model);
}

Views\Account\ExternalLoginConfirmation.cshtml 파일에 생년월일 및 홈타운을 추가합니다.

@model MvcAuth.Models.ExternalLoginConfirmationViewModel
@{
    ViewBag.Title = "Register";
}
<h2>@ViewBag.Title.</h2>
<h3>Associate your @ViewBag.LoginProvider account.</h3>

@using (Html.BeginForm("ExternalLoginConfirmation", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()

    <h4>Association Form</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <p class="text-info">
        You've successfully authenticated with <strong>@ViewBag.LoginProvider</strong>.
            Please enter a user name for this site below and click the Register button to finish
            logging in.
    </p>
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.HomeTown, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.HomeTown, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.HomeTown)
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.BirthDate, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.TextBoxFor(m => m.BirthDate, new { @class = "form-control" })
            @Html.ValidationMessageFor(m => m.BirthDate)
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="btn btn-default" value="Register" />
        </div>
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Facebook 계정을 애플리케이션에 다시 등록하고 새 생년월일 및 홈 타운 프로필 정보를 추가할 수 있는지 확인할 수 있도록 멤버 자격 데이터베이스를 삭제합니다.

솔루션 탐색기모든 파일 표시 아이콘을 클릭한 다음 Add_Data\aspnet-MvcAuth-dateStamp.mdf<>를 마우스 오른쪽 단추로 클릭하고 삭제를 클릭합니다.

솔루션 탐색기 페이지를 보여 주는 스크린샷 모든 파일 표시 아이콘 및 M v c 인증 멤버 자격 데이터베이스가 강조 표시됩니다.

도구 메뉴에서 NuGet 패키지 관리자를 클릭한 다음 PMC(패키지 관리자 콘솔)를 클릭합니다. PMC에서 다음 명령을 입력합니다.

  1. Enable-Migrations
  2. Add-Migration Init
  3. Update-Database

애플리케이션을 실행하고 FaceBook 및 Google을 사용하여 일부 사용자를 로그인하고 등록합니다.

멤버 자격 데이터 검사

보기 메뉴에서 서버 Explorer 클릭합니다.

Visual Studio 보기 드롭다운 메뉴를 보여 주는 스크린샷 서비스 Explorer 옵션이 강조 표시되어 있습니다.

AspNetUsers를 마우스 오른쪽 단추로 클릭하고 테이블 데이터 표시를 클릭합니다.

서버 Explorer 메뉴 옵션을 보여 주는 스크린샷 A의 p Net 사용자 및 테이블 데이터 표시 옵션이 강조 표시됩니다.

HomeTownBirthDate 필드는 다음과 같습니다.

A의 p Net Users 테이블 데이터를 보여 주는 스크린샷. 테이블 데이터에는 I D, Home Town, 생년월일, Email 및 Email 확인됨 필드가 표시됩니다.

앱 로그오프 및 다른 계정으로 로그인

Facebook을 사용하여 앱에 로그온한 다음 로그아웃하고 다른 Facebook 계정(동일한 브라우저 사용)으로 다시 로그인하면 사용한 이전 Facebook 계정에 즉시 로그인됩니다. 다른 계정을 사용하려면 Facebook으로 이동하여 Facebook에서 로그아웃해야 합니다. 다른 타사 인증 공급자도 동일한 규칙이 적용됩니다. 또는 다른 브라우저를 사용하여 다른 계정으로 로그인할 수 있습니다.

다음 단계

내 자습서에 따라 인증 및 SQL DB를 사용하여 ASP.NET MVC 앱 만들기를 수행하고 Azure App Service 배포합니다. 이 자습서는 이 자습서를 계속 진행하며 다음을 보여줍니다.

  1. Azure에 앱을 배포하는 방법
  2. 역할로 앱을 보호하는 방법.
  3. RequireHttpsAuthorize 필터를 사용하여 앱을 보호하는 방법입니다.
  4. 멤버 자격 API를 사용하여 사용자 및 역할을 추가하는 방법입니다.

ASP.NET 외부 인증 서비스의 작동 방식에 대한 좋은 설명은 Robert McMurray의 외부 인증 서비스를 참조하세요. Robert의 문서는 Microsoft 및 Twitter 인증을 사용하도록 설정하는 방법에 대해서도 자세히 설명합니다. Tom Dykstra의 뛰어난 EF/MVC 자습서 는 Entity Framework를 사용하여 작업하는 방법을 보여줍니다.